Once and for all, solve it NET publishing ECS

Most domestic developers use computers in Beijing time. In fact, there is no inconvenience in the process of daily development; However, when Alibaba cloud and other cloud servers are encountered, the system uses UTC time by default. At this time, the problem of time zone and time is a big problem that can not be ignored.

concept

First of all, to be clear, for a moment, whether you use UTC time or UTC+8 time, it is essentially a moment, which is the same. Our goal in dealing with date and time is also to ensure that this time will not be out of alignment due to different time zones.

DateTime and DateTimeOffset

There are two data types representing Time in. NET (the new Date and Time are not discussed). There are already students about these two data types It's very clear , many Alibaba cloud servers use UTC time. At this time, if DateTime is used, it is difficult to specify the time zone (Kind only has UTC and Local, and does not support a specific time zone). Therefore, we should give priority to using DateTimeOffset.

TimeZoneInfo

When used across time zones, time zone information is very important NET uses the TimeZoneInfo class to represent the time zone information. This class provides some static methods that can be used to find time zones, create time zones, and so on. At first, I was inclined to use these methods to find the information of Dongba District, but I found that methods such as ConvertTimeBySystemTimeZoneId and FindSystemTimeZoneById depend on the definitions in the system. Different systems may be different, and their own definitions are safer. Therefore, I used CreateCustomTimeZone to create a new time zone.

Unix timestamp is compared with UTC standard time in 1970. Therefore, in the process of processing, the time representation of DateTime should be converted into UTC time. The following code uses TimeZoneInfo to realize time conversion and DateTime data type. If you use DateTimeOffset instead, this type is more friendly for converting to Unix timestamp.

internal static class DateTimeExtension
{
    private static readonly TimeZoneInfo gmt8 = TimeZoneInfo.CreateCustomTimeZone("GMT+8", TimeSpan.FromHours(8), "China Standard Time", "(UTC+8)China Standard Time");
    
    public static long ToUnixTime(this DateTime datetime)
    {
        DateTime dateTimeUtc = datetime;
        if (datetime.Kind != DateTimeKind.Utc)
        {
            dateTimeUtc = datetime.ToUniversalTime();
        }

        if (dateTimeUtc.ToUniversalTime() <= DateTime.UnixEpoch)
        {
            return 0;
        }

        return (long)(dateTimeUtc - DateTime.UnixEpoch).TotalMilliseconds;
    }

    public static DateTime ToDateTime(this long unixTimestamp)
    {
        DateTime time = DateTime.UnixEpoch.AddMilliseconds(unixTimestamp);
        return TimeZoneInfo.ConvertTimeFromUtc(time, gmt8);
    }

    public static DateTime ToDateTime(this long unixTimestamp, int timezone)
    {
        DateTime time = DateTime.UnixEpoch.AddMilliseconds(unixTimestamp);
        return time.AddHours(timezone);
    }
}

In fact, as long as the time zone is correct, you can also use the methods provided by netizens for conversion.

// Code from https://stackoverflow.com/questions/5615538/parse-a-date-string-into-a-certain-timezone-supporting-daylight-saving-time
public DateTimeOffset ParseDateExactForTimeZone(string dateTime, TimeZoneInfo timezone)
{
    var parsedDateLocal = DateTimeOffset.ParseExact(dateTime, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
    var tzOffset = timezone.GetUtcOffset(parsedDateLocal.DateTime);
    var parsedDateTimeZone = new DateTimeOffset(parsedDateLocal.DateTime, tzOffset);
    return parsedDateTimeZone;
}

Practice Guide

In the process of processing date and time, if TimeZone Info is added, the program will become very troublesome, especially when the Id and name of various timezones are not unified in different systems, it is prone to various problems. What I want is to avoid using it and talk about my handling principles.

  1. DateTime does not use DateTime class, but all use DateTimeOffset type
  2. The internal processing of the system uses UTC standard time for data representation
  3. In the case of string conversion to DataTimeOffset, the hour offset of the time zone is explicitly specified
  4. Directly use the addition and subtraction of time to avoid the increase of code complexity caused by the information conversion of time zone
  5. [optional] if 2038 is not considered, Unix timestamp can be considered to simplify time representation

The idea is to force the time represented by the string, add the UTC standard time zone information, and then correct the time difference.

public static class DateTimeExtension
{
    public static long? ParseUnixTimeMillisecondsWithTimeZone(string datetimeString, string format = "yyyyMMddHHmmss", int timezoneOffset = 8)
    {
    	//Note the key parameter datetimestyles Assumeuniversal is to set the data to be UTC. Whether it is UTC or not, it is forcibly specified as UTC, and then adjusted to the correct time according to the information of the time zone.
    	//The given data is the time of Dongba District, but with this parameter, the actual time will be advanced by 8 hours. Therefore, it is necessary to directly subtract 8 hours from the following data. If it is the time of other regions, the same operation is required.
        if (!DateTimeOffset.TryParseExact(datetimeString, format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTimeOffset time)) return null;
        DateTimeOffset dateTimeUtcOffset = time.AddHours(-timezoneOffset);
        return dateTimeUtcOffset.ToUnixTimeMilliseconds();
    }

    public static DateTimeOffset ToDateTime(this long unixTimestamp) => DateTimeOffset.FromUnixTimeMilliseconds(unixTimestamp);
}

For ASP NET COREļ¼ŒJSON.NET will automatically process the date format conforming to the ISO8601 specification. As long as the data type is specified as DateTimeOffset, it can be converted accurately.

reference resources

Keywords: C# .NET

Added by anand_ragav on Thu, 27 Jan 2022 22:07:37 +0200