【问题标题】:Handling Time zone in C#在 C# 中处理时区
【发布时间】:2023-03-15 22:24:01
【问题描述】:

我需要实现的是, 显示带有组合框(包含所有时区)和组合框下方复选框的 UI。 仅当时区(选定的组合框项目)支持夏令时时才应显示该复选框。在呈现 UI 控件时,还要根据上次配置选中/取消选中复选框。

现在 C# 中的 TimeZoneInfo 类允许我获取时区列表(Combobox 的数据)。 但是 TimeZoneInfo 类中的 SupportsDayLightSaving 属性在 Checkbox 被选中时表示 true,在 没有复选框或 Checkbox 未选中时表示 false。

那么我如何通过 C# 确定,

1.时区是否支持夏令时(例如:印度标准时间不支持夏令时) 2.如果时区支持夏令时,是否启用夏令时(复选框被选中/取消选中)。

编辑: 如果我之前没有正确解释,这里是更详细的信息。 我想做什么:

  1. 显示/隐藏复选框(做出此决定的 if 条件是什么)
  2. 如果显示复选框,请选中/取消选中复选框(做出此决定的 if 条件是什么)。

PS:根据 MSDN SupportsDaylightSavingTime 属性,如果选中复选框,则值为 true,如果未选中复选框或时区不支持 DST,则值为 false。有了这个属性,如果值为 false,那么我无法确定是隐藏复选框还是显示它并取消选中复选框。 例如:对于印度标准时间,我不应该显示复选框,为此,如果我必须依赖属性值,那么我会将其设为 false,我可以将其隐藏。 但是考虑到我们有柏林时区(+1 UTC),使用控制面板设置未选中复选框,那么我会将属性值检索为 false 并应用上述逻辑将隐藏复选框,但在这里我想显示未选中状态的复选框。

使用答案编辑: 看起来我无法正确解释问题,对此我深表歉意。 经过长时间的谷歌搜索和搜索,我可以看到 .NET 没有提供 API 来支持我的需求。因此提出了一个解决方案,

检查 SupportsDaylightSavingsTime 属性是否为 true , if then 显示选中状态的复选框。如果上述属性值为 false ,则检查注册表中的 DynamicDaylightTimeDisabled 值 (HKLM\System\CurrentControlSet\Control\TimeZoneInformation) 。因为这里的 false 并不意味着时区不支持 DST,而是它也可以被禁用。如果值为 1 ,则显示未选中状态的复选框(因为它支持 DST 但目前已禁用)。如果值为 0 ,则不显示复选框。(因为时区不支持 DST)。

    //get the time zone info for the currently selected time zone.
        if (timeZoneInfo.SupportsDaylightSavingsTime)
        {
            //Show the checkbox.
            //Mark the checkbox state as checked.
        }
        else
        {
            //doesnt mean that the timezone doesnt support DST.
            int regValue;//Get the reg value of DynamicDaylightTimeDisabled  in 
            //location HKLM\System\CurrentControlSet\Control\TimeZoneInformation\

            if(regValue == 0)
            {
                //Donot show the checkbox.
            }
            if(regValue == 1)
            {
                //show the checkbox.
                //Mark the checkbox state as unchecked.
            }

        }

【问题讨论】:

  • 您使用的是 Windows-Form、WPF、ASP.NET?
  • 它是一个 wpf 应用程序。但没关系,因为我解释 UI 只是为了理解。我的疑问是我需要用来检查我的两个条件的 API 是什么。 1.显示/隐藏复选框。 2.选中/取消选中复选框。

标签: c# .net wpf timezone


【解决方案1】:

1.时区是否支持夏令时(例如:印度标准时间不支持夏令时)

使用TimeZoneInfo.SupportsDaylightSavingTime 属性对其进行测试。

例如:

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
foreach(TimeZoneInfo zone in zones)
{
   if (! zone.SupportsDaylightSavingTime)
      Console.WriteLine(zone.DisplayName);
}

2.如果时区支持夏令时,是否启用夏令时(复选框被选中/取消选中)。

我假设您正在使用带有ListBox GUI 控件的 Windows 窗体应用程序,在这种情况下,连接到您的 ListBoxOnSelectedIndexChanged 事件并在那里进行 DayLightSupport 测试。

【讨论】:

  • 感谢您的回答。但是是的,我可以发现 SupportDaylightSavingTime 可用于确定 TimeZone 是否支持 DST。但这并不总是正确的。因为例如:如果我们从控制面板设置中取消选中柏林时区(+1 UTC,支持 DST)的复选框,并且如果我们编写代码来获取该时区的 SupportDayLightSavingTime 值,那么我们将得到一个值 false(如根据 MSDN 文档),但如果您看到此时区支持 dst。
  • 为了更清楚,我想首先显示或隐藏复选框(基于它是否支持 dst)第二个复选框应该被选中或取消选中(基于之前的配置),那么将是两个条件(即如果我需要使用的检查)。如果您清楚地看到我有两个条件,但 .NET 只为我提供了一个检查 SupportsDaylightSavingTime 那么另一个检查可能是什么?
【解决方案2】:

也许这段代码会有所帮助,但它都是背后的代码和简单的东西。

在 cmets 之后更新。

一些xaml:

<Window x:Class="TimeZoneDaylightTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Loaded="MainWindow_OnLoaded"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <ListBox Height="200" Name="TimeZonesListBox" SelectionChanged="TimeZonesListBox_OnSelectionChanged">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding DisplayName}" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <CheckBox Height="30" Name="SupportsDaylightCheckBox">Supports DayLightSaving</CheckBox>
        </StackPanel>
    </Grid>
</Window>

和后面的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        TimeZonesListBox.ItemsSource = TimeZoneInfo.GetSystemTimeZones();
    }

    private void TimeZonesListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var tz = TimeZonesListBox.SelectedItem as TimeZoneInfo;
        if (tz != null)
            SupportsDaylightCheckBox.Visibility = tz.SupportsDaylightSavingTime ? Visibility.Visible : Visibility.Hidden;
    }
}

【讨论】:

  • 你快到了。在更改的选择中,我想要实现的是隐藏或显示复选框,我该怎么做。好的,我的意思是,我将使用什么条件来确定是显示还是隐藏复选框?
  • 啊,等一下,我认为您应该寻找的是复选框的 Visibility 属性,我会在一分钟内更新示例...
  • 现在你在正确的轨道上,那么我应该使用什么条件来检查/取消选中控件??
【解决方案3】:

仅当时区(选定的组合框项)支持夏令时时才应显示该复选框。在呈现 UI 控件时,还要根据上次配置选中/取消选中复选框。

如果我正确理解您的情况,这里有两件事。为了显示/隐藏复选框,您需要检查所选时区是否支持 DST,然后设置其可见性。但是为了根据之前的配置将其设置为选中/取消选中,您需要以某种方式存储它 - 很可能存储在数据库中,但我不确定实际情况。

作为您的代码外观的一个想法,它可能看起来类似于:

private void TimeZonesListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    TimeZoneInfo info = (TimeZoneInfo)timeZoneListBox.SelectedItem;
    dstCheckBox.Visible = info.SupportsDaylightSavingTime;
    dstCheckBox.Checked = GetPreviousConfiguration(info);
}

private bool GetPreviousConfiguration(TimeZoneInfo timezone)
{
     //Code to lookup previous config.
}

希望这会为您指明正确的方向。

【讨论】:

    【解决方案4】:

    您的解释中缺少什么,但我想我可以从 cmets 推断出您正在专门谈论此复选框:

                     

    只有在您使用 TimeZoneInfo.Local 时才会发挥作用。换句话说,我总是可以这样做:

    var tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    Debug.WriteLine(tzi.SupportsDaylightSavingTime);
    

    无论是否设置了该复选框,tzi.SupportsDaylightSavingTime 都会返回 true,因为该区域的数据支持它。

    但是使用

    var tzi = TimeZoneInfo.Local;
    Debug.WriteLine(tzi.SupportsDaylightSavingTime);
    

    如果未选中该框,则结果可能为假,即使区域数据支持它也是如此。这在in the MSDNin this excellent article 进行了讨论。

    如果我的理解正确,您想具体了解“自动调整夏令时时钟”是否已清除,以便您可以构建一个模仿 Windows 中的 UI?

    正如您在一次编辑中指出的那样,您可以根据需要从注册表中获取此信息,但您需要检查两个不同的键,而不仅仅是一个。每the article

    根据所使用的 Windows 版本,此复选框会将“DisableAutoDaylightTimeSet”或“DynamicDaylightTimeDisabled”注册表项值设置为一 (1):

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
        "DynamicDaylightTimeDisabled"=dword:00000001`
    
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
        "DisableAutoDaylightTimeSet"=dword:00000001
    

    不过,有一种更简单的方法可以检测到这种情况:

    static bool LocalDstDisabled()
    {
        TimeZoneInfo localZone = TimeZoneInfo.Local;
        TimeZoneInfo realZone = TimeZoneInfo.FindSystemTimeZoneById(localZone.Id);
    
        return realZone.SupportsDaylightSavingTime &&
               !localZone.SupportsDaylightSavingTime;
    }
    

    【讨论】:

    • 另外,将来您可能会考虑省略有关您自己的本地 UI 的部分,因为我认为您并不是真的在寻求有关如何显示复选框的帮助。您的问题范围越窄,您获得相关答案的可能性就越大。
    • 马特,在他最后的评论之后我很困惑,我现在想放弃这个 q :)
    • 哦,马特 :) 最后这是我一直在寻找的答案。也许我可以从一开始就更好地解释它,抱歉没有用正确的方式。不过,您指出了正确的答案。也感谢您的链接。
    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 2019-05-05
    • 2010-09-25
    • 1970-01-01
    • 2016-05-29
    • 2011-06-01
    • 2011-06-27
    相关资源
    最近更新 更多