处理C#中的时区

时间:2014-03-26 12:25:36

标签: c# .net wpf timezone

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

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

那么如何通过C#确定

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

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

  1. 显示/隐藏复选框(采取此决定的if条件是什么)
  2. 如果显示复选框,请选中/取消选中复选框(判断条件的条件是什么)。
  3. PS:根据MSDN SupportsDaylightSavingTime属性,如果选中该复选框,则该值为true;如果未选中复选框或时区不支持DST,则该值为false。使用此属性,如果值为false,则无法确定是隐藏复选框还是显示该复选框并取消选中该复选框。 例如:对于印度标准时间,我不应该显示复选框,因为如果我必须依赖属性值,那么我会把它作为假,我可以隐藏它。 但是考虑我们有柏林时区(+1 UTC),并且使用控制面板设置未选中复选框,然后我将检索属性值为false并应用上述逻辑将隐藏复选框,但在此我想要显示未选中状态的复选框。

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

    检查SupportsDaylightSavingsTime属性是否为true, if if然后显示选中状态的复选框。如果上述属性值为false,则检查注册表中的DynamicDaylightTimeDisabled值(HKLM \ System \ CurrentControlSet \ Control \ TimeZoneInformation)。因为这里的错误并不意味着时区不支持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.
                }
    
            }
    

4 个答案:

答案 0 :(得分:4)

你的解释中缺少什么,但我想我可以从评论中推断出你是在谈论这个复选框:

Time Zone Setting

只有在使用TimeZoneInfo.Local时才会发挥作用。换句话说,我总能做到这一点:

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

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

但是使用

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

如果未选中该框,则结果可能为false,即使区域数据支持该框也是如此。我们讨论了in the MSDN以及in this excellent article

如果我理解正确,您希望明确知道“自动调整夏令时的时钟”是否已清除,以便您可以构建一个模仿Windows中的时钟的用户界面?

正如您在其中一个编辑中所指出的,如果您愿意,可以从注册表中获取此信息,但您需要检查两个不同的密钥,而不仅仅是一个。每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;
}

答案 1 :(得分:1)

  

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

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

例如:

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

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

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

答案 2 :(得分:0)

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

评论后更新。

一些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;
    }
}

答案 3 :(得分:0)

  

仅当时区(选定的组合框项目)支持夏令时时,才会显示复选框。同时在呈现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.
}

希望这能指出你正确的方向。