使用 StringFormat 将 XAML 中的时间戳(长类型)转换为日期和时间

发布于 2025-01-16 22:54:11 字数 574 浏览 2 评论 0原文

我有一个 long 类型的时间戳属性,我已将其绑定到 ListView 列。 使用 XAML,我尝试将此时间戳(long 类型)转换为日期和时间,具体取决于正在运行的计算机的当前区域设置。

我想得到这样的信息:

mm/dd/yyyy HH:mmdd/mm/yyyy HH:mm (24 小时格式)

mm /dd/yyyy hh:mm PM 或 dd/mm/yyyy hh:mm PM(12 小时格式),

具体取决于计算机区域设置。

所以我使用 StringFormat:

<GridViewColumn Header="Id"
                DisplayMemberBinding="{Binding Path=Timestamp, StringFormat='g'}"/>

但它似乎不起作用。在网格视图单元格中,它显示为一个长数字。

I have a timestamp property which is a long type and I have bound it to a ListView column.
Using XAML I am trying to convert this timestamp (long type) into a date and time dependent on the current regional settings of the machine on which is running.

I would like to get someting like this:

mm/dd/yyyy HH:mm or dd/mm/yyyy HH:mm (24 hour format)

or

mm/dd/yyyy hh:mm PM or dd/mm/yyyy hh:mm PM (12 hour format)

depending on the machine regional settings.

So I use StringFormat:

<GridViewColumn Header="Id"
                DisplayMemberBinding="{Binding Path=Timestamp, StringFormat='g'}"/>

But it seems it is not working. In the grid view cell it is shown as a long number.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泪眸﹌ 2025-01-23 22:54:11

g通用格式说明符,它将把long显示为数字。

通用(“G”)格式说明符将数字转换为更紧凑的定点或科学记数法,具体取决于数字的类型以及是否存在精度说明符。

日期格式化机制不能直接与long一起使用。 DateTime 对于表示日期和时间是明确的,但是如何将 long 解释为秒、毫秒,从哪里解释?请参阅 的文档标准日期和时间格式字符串

标准日期和时间格式字符串使用单个字符作为格式说明符来定义 DateTimeDateTimeOffset 值的文本表示形式。

显而易见的解决方案是通过 DateTime 类型的属性公开日期,而不是 long。然后,您可以在 XAML StringFormat 中使用标准和自定义日期格式说明符。

public DateTime Timestamp { get; }

或者,您可以创建一个自定义值转换器,将 long 转换为 DateTime

public class LongToDateConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      if (!(value is long milliseconds))
         return value;

      var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
      return dateTime.AddMilliseconds(milliseconds).ToLocalTime();

      // Alternative in > .NET Core 2.1
      //return DateTime.UnixEpoch.AddMilliseconds(milliseconds);
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      return new NotImplementedException();
   }
}

在范围内的任何资源中创建转换器的实例,例如Window.Resources

<Window.Resources>
   <local:LongToDateConverter x:Key="LongToDateConverter"/>
</Window.Resources>

自从转换发生在格式化之前,您可以保留StringFormat

如果设置 ConverterStringFormat 属性,则转换器将首先应用于数据值,然后应用 StringFormat

<GridViewColumn Header="Id"
                DisplayMemberBinding="{Binding Path=Timestamp, Converter={StaticResource LongToDateConverter}, StringFormat='g'}"/>

您可以参考 自定义日期和时间格式字符串以创建所需的格式字符串。

StringFormat='MM/dd/yyyy HH:mm'
StringFormat='dd/MM/yyyy HH:mm'

StringFormat='MM/dd/yyyy hh:mm'
StringFormat='dd/MM/yyyy'

更新您的评论:

我忘了在我的帖子中说(抱歉)这个长时间戳是通过执行 DateTime.UtcNow.ToFileTimeUtc() [...]

我假设是 Unix 时间戳。正如您所看到的,long 非常模糊。在这种情况下,您可以按照 文档

ToFileTimeUtc() 方法有时用于将本地时间转换为 UTC,随后通过调用 FromFileTimeUtc(Int64) 方法和 ToLocalTime 来恢复它() 方法。 但是,如果原始时间表示本地时区中的无效时间,则两个本地时间值将不相等。

转换器方法将执行此操作。

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
   if (!(value is long milliseconds))
      return value;

   return DateTime.FromFileTimeUtc(milliseconds).ToLocalTime();
}

The g is the general format specifier, which will display the long as number.

The general ("G") format specifier converts a number to the more compact of either fixed-point or scientific notation, depending on the type of the number and whether a precision specifier is present.

The date formatting mechanism does not work directly with long. A DateTime is unambiguous for representing a date and time, but how do you interpret long, as seconds, as milliseconds, from where? See the documentation for Standard date and time format strings.

A standard date and time format string uses a single character as the format specifier to define the text representation of a DateTime or a DateTimeOffset value.

The obvious solution is to expose the dates through a property of type DateTime, not long. Then you can use the standard and custom date format specifiers in XAML StringFormat.

public DateTime Timestamp { get; }

Alternatively, you can create a custom value converter that converts the long to a DateTime.

public class LongToDateConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      if (!(value is long milliseconds))
         return value;

      var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
      return dateTime.AddMilliseconds(milliseconds).ToLocalTime();

      // Alternative in > .NET Core 2.1
      //return DateTime.UnixEpoch.AddMilliseconds(milliseconds);
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      return new NotImplementedException();
   }
}

Create an instance of the converter in any resources in scope, e.g. Window.Resources.

<Window.Resources>
   <local:LongToDateConverter x:Key="LongToDateConverter"/>
</Window.Resources>

Since the conversion happens before formatting, you can keep the StringFormat.

If you set the Converter and StringFormat properties, the converter is applied to the data value first, and then the StringFormatis applied.

<GridViewColumn Header="Id"
                DisplayMemberBinding="{Binding Path=Timestamp, Converter={StaticResource LongToDateConverter}, StringFormat='g'}"/>

You can refer to Custom date and time format strings to create the desired format string.

StringFormat='MM/dd/yyyy HH:mm'
StringFormat='dd/MM/yyyy HH:mm'

StringFormat='MM/dd/yyyy hh:mm'
StringFormat='dd/MM/yyyy'

Update for your comment:

I forgot to say in my post (sorry) that this long timestamp was obtained by doing DateTime.UtcNow.ToFileTimeUtc() [...]

I assumed the Unix timestamp. As you can see, a long is pretty ambiguous. In this case you can convert the long back as stated in the documentation.

The ToFileTimeUtc() method is sometimes used to convert a local time to UTC, and subsequently to restore it by calling the FromFileTimeUtc(Int64) method followed by the ToLocalTime() method. However, if the original time represents an invalid time in the local time zone, the two local time values will not be equal.

The converter method would do exactly this.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
   if (!(value is long milliseconds))
      return value;

   return DateTime.FromFileTimeUtc(milliseconds).ToLocalTime();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文