【问题标题】:What is the best way to get a formatted string to represent UTC offset? [duplicate]获取格式化字符串以表示 UTC 偏移量的最佳方法是什么? [复制]
【发布时间】:2011-06-20 05:09:49
【问题描述】:

我需要像这样格式化日期:20110202192008-0500。以下代码可以解决问题,但我想知道在 c# 3.5 中是否有更好/更清洁的方法来做到这一点。谢谢!!

  var date = DateTime.Now;
  var strDate = TimeZoneInfo.ConvertTimeToUtc(date).ToString("yyyyMMddHHmmss");
  var offsetHours = TimeZoneInfo.Local.GetUtcOffset(date).Hours.ToString("00");
  var offsetMinutes = TimeZoneInfo.Local.GetUtcOffset(date).Minutes.ToString("00");
  Console.Write(string.Concat(strDate, offsetHours, offsetMinutes));

【问题讨论】:

  • 只是为了确保我做对了:您要显示 UTC 日期和时间,然后提供偏移量以便读者自己进行数学计算? (因此示例显示当地时间 14:20:08。)
  • 完全正确。只是想知道是否有更简洁的方法来获取字符串。

标签: c# datetime formatting timezone


【解决方案1】:

这个怎么样:

.NET 4

 var utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
 Console.WriteLine(DateTime.UtcNow.ToString("yyyyMMddHHmmss") + ((utcOffset < TimeSpan.Zero) ? "-" : "+") + utcOffset.ToString("hhmm"));

.NET 3.5

 var utcAlmostFormat = DateTime.UtcNow.ToString("yyyyMMddHHmmss") + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
 var utcFormat = System.Text.RegularExpressions.Regex.Replace(utcAlmostFormat, @"(\d\d):(\d\d):(\d\d)",@"$1$2");
 Console.WriteLine(utcFormat);

Go Steelers(来自拉斯维加斯大道的一个人)

【讨论】:

  • TimeSpan 上的 ToString 在 3.5 中没有格式重载 :(
  • @Mike - 啊该死的,好吧,是的,我会使用你所拥有的,或者在 utcOffset.ToString() 版本上使用子字符串。
  • @Mike - 我添加了另一个在 3.5 上应该没问题的版本,只是使用正则表达式来格式化输出。
  • 第一个例子是错误的。你有 ToString("hhss")。应该是 ToString("hhmm")
【解决方案2】:

如果您有DateTimeOffset,自定义说明符zzz 将输出时区偏移量,但采用更标准的“+HH:mm”格式。如果你不想要冒号,字符串替换就可以了。

Debug.WriteLine(DateTimeOffset.Now.ToString("yyyyMMddHHmmsszzz").Replace(":", ""));
// Result: "20110202153631-0500"

【讨论】:

  • 那不会产生 UTC 时间。
  • 指定时间和 UTC 偏移量的标准方法是本地时间,以及与 UTC 的偏移量。如果您使用 UTC 时间,以及尚未应用到时间的本地偏移量,那么当有人假设它是以标准方式完成时,您就是在为自己设置错误。
  • 我同意,只是给 OP 他想要的东西 :)
  • 我将仔细检查以确保格式要求正确,因为这是有道理的。
【解决方案3】:

以下是一些适用于 .Net 3.5 和 .Net 4.0 的扩展方法,它们将以非常直接的方式完全满足您的要求:

public static string ToStringWithOffset(this DateTime dt)
{
  return new DateTimeOffset(dt).ToStringWithOffset();
}

public static string ToStringWithOffset(this DateTime dt, TimeSpan offset)
{
  return new DateTimeOffset(dt, offset).ToStringWithOffset();
}

public static string ToStringWithOffset(this DateTimeOffset dt)
{
  string sign = dt.Offset < TimeSpan.Zero ? "-" : "+";
  int hours = Math.Abs(dt.Offset.Hours);
  int minutes = Math.Abs(dt.Offset.Minutes);

  return string.Format("{0:yyyyMMddHHmmss}{1}{2:00}{3:00}", dt, sign, hours, minutes);
}

您现在可以在任何您希望的 DateTime 或 DateTimeOffset 上调用它们。例如:

string s = DateTime.Now.ToStringWithOffset();

string s = DateTimeTimeOffset.Now.ToStringWithOffset();

TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(someDate);
string s = someArbitraryTime.ToStringWithOffset(offset);

或您能想到的任何其他方式。

【讨论】:

    【解决方案4】:

    我们发现 DateTimeOffset.ToString("o") 最适合。示例:

    DateTime.UtcNow.UtcToDateTimeOffset(User.GetTimeZone()).ToString("o");
    

    如果您需要从 DateTime 转换,请使用辅助方法,例如:

        /// <summary>Converts from a UTC DateTime to the user's local DateTime</summary>
        /// <param name="utcDateTime">UTC DateTime</param>
        /// <param name="timeZoneInfo">The time zone info.</param>
        /// <returns>The DateTime in the user's time zone</returns>
        public static DateTimeOffset UtcToDateTimeOffset(this DateTime utcDateTime, TimeZoneInfo timeZoneInfo = null)
        {
            if (utcDateTime.Kind != DateTimeKind.Utc)
            {
                throw new InvalidTimeZoneException("Converting UTC to Local TimeZone, but was not UTC.");
            }
    
            DateTimeOffset dto = new DateTimeOffset(utcDateTime, TimeSpan.Zero);
    
            return timeZoneInfo.IsNotNull() ? dto.ToOffset(timeZoneInfo.GetUtcOffset(dto)) : dto;
        }
    

    【讨论】:

      【解决方案5】:

      您可以使用DateTime Standard Formats 之一或创建Custom Format

      // Round-trip date/time pattern: "O", "o"
      DateTime.Now.ToString("o") // "2018-01-15T11:00:50.5604578-05:00"
      DateTime.UtcNow.ToString("o") // "2018-01-15T16:00:50.5604578Z"
      
      // Universal sortable date/time pattern: "u"
      DateTime.Now.ToString("u") // "2018-01-15 16:00:50.5604578Z"
      DateTime.UtcNow.ToString("u") // "2018-01-15 16:00:50.5604578Z"
      
      // Custom format
      DateTime.Now.ToString("yyyyMMddHHmmssK") // "20180115160050-05:00"
      DateTime.UtcNow.ToString("yyyyMMddHHmmssK") // "20180115160050Z"
      

      【讨论】:

        【解决方案6】:

        尝试使用 var date = DateTimeOffset.Now; var timestamp = $"{date:yyyy-MM-dd'T'HH:mm:ss.fff}{date.Offset.Ticks:+;-;}{date.Offset:hhmm}"; ...或类似的东西

        【讨论】:

        • 应该是 {date.Offset:hh\\:mm}
        【解决方案7】:

        我认为有很多方法,例如:

          var offset = TimeZoneInfo.Local.BaseUtcOffset;
          string result = DateTime.UtcNow.ToString("yyyyMMddHHmmss") + offset.Hours.ToString("00") + offset.Minutes.ToString("00");
        

        【讨论】:

        • 我不认为你想要 - 在那里,因为这意味着 UTC 偏移量将始终为负数。
        • -1:它是当前时区的偏移量,与夏令时无关。目前在巴黎,我们处于 UTC+2,但此代码显示的偏移量为 1 小时
        猜你喜欢
        • 2011-01-09
        • 1970-01-01
        • 1970-01-01
        • 2010-10-25
        • 2021-01-21
        • 2023-03-20
        • 2011-01-29
        • 1970-01-01
        • 2011-08-28
        相关资源
        最近更新 更多