How to get "DateTime.Now" in the Gregorian format when client calendar is non-Gregorian?
Asked Answered
U

1

7

How can I get DateTime.Now in Gregorian calender when client calendar is non-Gregorian?

My project is a Silverlight with C# code and client default calender is not predicted.

Unbridled answered 16/9, 2012 at 5:58 Comment(2)
Does Node Time have what you need? code.google.com/p/noda-timeMassorete
thank you arran, I'm looking for a solution without using dll.Unbridled
M
10

A DateTime value has no format. Internally it's just a count of ticks since the epoch, 0001-01-01 00:00 in .NET. Formatting is when you call ToString.

Just use a different CultureInfo for the culture that has the calendar you want, e.g.

CultureInfo french = CultureInfo.GetCultureInfo( "fr-FR" );
    
String nowStr = DateTime.Now.ToString( french );
Console.WriteLine( nowStr ); // "16/09/2012 05:58:00"

Use CultreInfo.InvariantCulture if you just to use a predictable Western culture with a Gregorian calendar.

While InvariantCulture is invariant it uses en-US's MM/dd/yyyy date format which the entire rest of the world doesn't use so I recommend always using ISO 8601 instead...

Copy this code into your project:

using System;
using System.Globalization;

public static class CultureInfo2
{
    /// <summary>A read-only clone of <see cref="P:System.Globalization.CultureInfo.InvariantCulture" />, except the <see cref="P:System.Globalization.CultureInfo.DateTimeFormat" /> is replaced with a <see cref="T:System.Globalization.DateTimeFormatInfo" /> configured to use ISO 8601 formatting for dates and times.</summary>
    public static CultureInfo InvariantCultureWithIso8601 { get; } = CreateInvariantCultureWithIso8601();

    private static CultureInfo CreateInvariantCultureWithIso8601()
    {
        CultureInfo obj = (CultureInfo)CultureInfo.InvariantCulture.Clone();
        obj.DateTimeFormat = new DateTimeFormatInfo
        {
            AMDesignator = "AM",
            DateSeparator = "-",
            FirstDayOfWeek = DayOfWeek.Monday,
            CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek,
            FullDateTimePattern = "yyyy-MM-dd HH':'mm':'ss", // NOTE: Use `"yyyy-MM-DD'T'HH:mm:ss"` for stricter ISO 8601 compliance.
            LongDatePattern = "yyyy-MM-dd ddd", // <-- This is subjective.
            LongTimePattern = "HH':'mm':'ss",
            MonthDayPattern = "MMMM dd",
            PMDesignator = "PM",
            ShortDatePattern = "yyyy-MM-dd",
            ShortTimePattern = "HH:mm",
            TimeSeparator = ":",
            YearMonthPattern = "yyyy MMMM"
        };
        return CultureInfo.ReadOnly(obj);
    }

    public static String ToStringInvariant( this DateTime value )
    {
        return value.ToString( provider: InvariantCultureWithIso8601 );
    }

    public static String ToStringInvariant( this DateTime value, String format )
    {
        return value.ToString( format: format, provider: InvariantCultureWithIso8601 );
    }
}

And use it like so:

String nowStr = DateTime.Now.ToStringInvariant();
Console.WriteLine( nowStr ); // "2012-09-16 05:58:00"
Materially answered 16/9, 2012 at 13:35 Comment(2)
thank you Dai,I changed DateTime Filed to Long, and saved DateTime.Now.Ticks from client project then I saved it.Unbridled
The .Ticks property shouldn't be used to recreate a DateTime value because a DateTime value also contains information on its UTC/Local state. If you want to serialize a DateTime use DateTime.ToBinary() (it still returns an Int64, but it contains the UTC/Local information, whereas .Ticks does not). To de-serialize use DateTime.FromBinary(Int64).Materially

© 2022 - 2024 — McMap. All rights reserved.