Instrukcje: Zapisywanie stref czasowych w zasobie osadzonym
Aplikacja z obsługą stref czasowych często wymaga obecności określonej strefy czasowej. Jednak ze względu na to, że dostępność poszczególnych TimeZoneInfo obiektów zależy od informacji przechowywanych w rejestrze systemu lokalnego, nawet niestandardowe dostępne strefy czasowe mogą być nieobecne. Ponadto informacje o niestandardowych strefach czasowych utworzone za pomocą CreateCustomTimeZone metody nie są przechowywane z innymi informacjami o strefie czasowej w rejestrze. Aby upewnić się, że te strefy czasowe są dostępne w razie potrzeby, można je zapisać, serializując je, a następnie przywrócić je, deserializując je.
Zazwyczaj serializowanie TimeZoneInfo obiektu odbywa się niezależnie od aplikacji obsługującej strefy czasowej. W zależności od magazynu danych używanego do przechowywania serializowanych TimeZoneInfo obiektów dane strefy czasowej mogą być serializowane w ramach procedury instalacji lub instalacji (na przykład gdy dane są przechowywane w kluczu aplikacji rejestru) lub w ramach procedury narzędzi, która jest uruchamiana przed skompilowaną ostateczną aplikacją (na przykład gdy serializowane dane są przechowywane w pliku zasobu XML platformy .NET (resx).
Oprócz pliku zasobu skompilowanego z aplikacją można użyć kilku innych magazynów danych na potrzeby informacji o strefie czasowej. Należą do nich następujące funkcje:
Rejestr. Należy pamiętać, że aplikacja powinna używać podklucza własnego klucza aplikacji do przechowywania niestandardowych danych strefy czasowej, a nie używania podkluczów HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.
Pliki konfiguracji.
Inne pliki systemowe.
Aby zapisać strefę czasową, serializując ją w pliku resx
Pobierz istniejącą strefę czasową lub utwórz nową strefę czasową.
Aby pobrać istniejącą strefę czasową, zobacz Instrukcje: uzyskiwanie dostępu do wstępnie zdefiniowanych obiektów strefy czasowej UTC i lokalnych oraz Instrukcje: tworzenie wystąpienia obiektu TimeZoneInfo.
Aby utworzyć nową strefę czasową, wywołaj jedno z przeciążeń CreateCustomTimeZone metody . Aby uzyskać więcej informacji, zobacz How to: Create time zones without adjustment rules (Jak tworzyć strefy czasowe bez reguł korekt) i How to: Create time zones with adjustment rules (Jak tworzyć strefy czasowe z regułami korekt).
Wywołaj metodę , ToSerializedString aby utworzyć ciąg zawierający dane strefy czasowej.
StreamWriter Utwórz wystąpienie obiektu, podając nazwę i opcjonalnie ścieżkę pliku resx do konstruktora StreamWriter klasy.
Utwórz wystąpienie ResXResourceWriter obiektu, przekazując StreamWriter obiekt do konstruktora ResXResourceWriter klasy.
Przekaż ciąg serializowany strefy czasowej do ResXResourceWriter.AddResource metody .
Wywołaj metodę ResXResourceWriter.Generate .
Wywołaj metodę ResXResourceWriter.Close .
StreamWriter Zamknij obiekt, wywołując jego Close metodę.
Dodaj wygenerowany plik resx do projektu programu Visual Studio aplikacji.
Korzystając z okna Właściwości w programie Visual Studio, upewnij się, że właściwość Akcja kompilacji pliku resx jest ustawiona na zasób osadzony.
Przykład
W poniższym przykładzie serializuje obiekt reprezentujący centralną TimeZoneInfo standardową TimeZoneInfo godzinę i obiekt reprezentujący czas Palmer Station, Antarktydy do pliku zasobów XML platformy .NET o nazwie SerializedTimeZones.resx. Środkowy czas standardowy jest zwykle definiowany w rejestrze; Palmer Station, Antarktyda jest niestandardową strefą czasową.
TimeZoneSerialization()
{
TextWriter writeStream;
Dictionary<string, string> resources = new Dictionary<string, string>();
// Determine if .resx file exists
if (File.Exists(resxName))
{
// Open reader
TextReader readStream = new StreamReader(resxName);
ResXResourceReader resReader = new ResXResourceReader(readStream);
foreach (DictionaryEntry item in resReader)
{
if (! (((string) item.Key) == "CentralStandardTime" ||
((string) item.Key) == "PalmerStandardTime" ))
resources.Add((string)item.Key, (string) item.Value);
}
readStream.Close();
// Delete file, since write method creates duplicate xml headers
File.Delete(resxName);
}
// Open stream to write to .resx file
try
{
writeStream = new StreamWriter(resxName, true);
}
catch (FileNotFoundException e)
{
// Handle failure to find file
Console.WriteLine("{0}: The file {1} could not be found.", e.GetType().Name, resxName);
return;
}
// Get resource writer
ResXResourceWriter resWriter = new ResXResourceWriter(writeStream);
// Add resources from existing file
foreach (KeyValuePair<string, string> item in resources)
{
resWriter.AddResource(item.Key, item.Value);
}
// Serialize Central Standard Time
try
{
TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
resWriter.AddResource(cst.Id.Replace(" ", string.Empty), cst.ToSerializedString());
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The Central Standard Time zone could not be found.");
}
// Create time zone for Palmer, Antarctica
//
// Define transition times to/from DST
TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0),
10, 2, DayOfWeek.Sunday);
TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0),
3, 2, DayOfWeek.Sunday);
// Define adjustment rule
TimeSpan delta = new TimeSpan(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1),
DateTime.MaxValue.Date, delta, startTransition, endTransition);
// Create array for adjustment rules
TimeZoneInfo.AdjustmentRule[] adjustments = {adjustment};
// Define other custom time zone arguments
string DisplayName = "(GMT-04:00) Antarctica/Palmer Time";
string standardName = "Palmer Standard Time";
string daylightName = "Palmer Daylight Time";
TimeSpan offset = new TimeSpan(-4, 0, 0);
TimeZoneInfo palmer = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, DisplayName, standardName, daylightName, adjustments);
resWriter.AddResource(palmer.Id.Replace(" ", String.Empty), palmer.ToSerializedString());
// Save changes to .resx file
resWriter.Generate();
resWriter.Close();
writeStream.Close();
}
Private Sub SerializeTimeZones()
Dim writeStream As TextWriter
Dim resources As New Dictionary(Of String, String)
' Determine if .resx file exists
If File.Exists(resxName) Then
' Open reader
Dim readStream As TextReader = New StreamReader(resxName)
Dim resReader As New ResXResourceReader(readStream)
For Each item As DictionaryEntry In resReader
If Not (CStr(item.Key) = "CentralStandardTime" Or _
CStr(item.Key) = "PalmerStandardTime") Then
resources.Add(CStr(item.Key), CStr(item.Value))
End If
Next
readStream.Close()
' Delete file, since write method creates duplicate xml headers
File.Delete(resxName)
End If
' Open stream to write to .resx file
Try
writeStream = New StreamWriter(resxName, True)
Catch e As FileNotFoundException
' Handle failure to find file
Console.WriteLine("{0}: The file {1} could not be found.", e.GetType().Name, resxName)
Exit Sub
End Try
' Get resource writer
Dim resWriter As ResXResourceWriter = New ResXResourceWriter(writeStream)
' Add resources from existing file
For Each item As KeyValuePair(Of String, String) In resources
resWriter.AddResource(item.Key, item.Value)
Next
' Serialize Central Standard Time
Try
Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
resWriter.AddResource(cst.Id.Replace(" ", String.Empty), cst.ToSerializedString())
Catch
Console.WriteLine("The Central Standard Time zone could not be found.")
End Try
' Create time zone for Palmer, Antarctica
'
' Define transition times to/from DST
Dim startTransition As TimeZoneInfo.TransitionTime = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#4:00:00 AM#, 10, 2, DayOfWeek.Sunday)
Dim endTransition As TimeZoneInfo.TransitionTime = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(#3:00:00 AM#, 3, 2, DayOfWeek.Sunday)
' Define adjustment rule
Dim delta As TimeSpan = New TimeSpan(1, 0, 0)
Dim adjustment As TimeZoneInfo.AdjustmentRule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(#10/1/1999#, Date.MaxValue.Date, delta, startTransition, endTransition)
' Create array for adjustment rules
Dim adjustments() As TimeZoneInfo.AdjustmentRule = {adjustment}
' Define other custom time zone arguments
Dim DisplayName As String = "(GMT-04:00) Antarctica/Palmer Time"
Dim standardName As String = "Palmer Standard Time"
Dim daylightName As String = "Palmer Daylight Time"
Dim offset As TimeSpan = New TimeSpan(-4, 0, 0)
Dim palmer As TimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, DisplayName, standardName, daylightName, adjustments)
resWriter.AddResource(palmer.Id.Replace(" ", String.Empty), palmer.ToSerializedString())
' Save changes to .resx file
resWriter.Generate()
resWriter.Close()
writeStream.Close()
End Sub
W tym przykładzie serializuje TimeZoneInfo obiekty, aby były dostępne w pliku zasobów w czasie kompilacji.
ResXResourceWriter.Generate Ponieważ metoda dodaje pełne informacje nagłówka do pliku zasobu XML platformy .NET, nie może służyć do dodawania zasobów do istniejącego pliku. Przykład obsługuje to, sprawdzając plik SerializedTimeZones.resx i, jeśli istnieje, przechowując wszystkie jego zasoby inne niż dwie serializowane strefy czasowe do obiektu ogólnego Dictionary<TKey,TValue> . Istniejący plik zostanie usunięty, a istniejące zasoby zostaną dodane do nowego pliku SerializedTimeZones.resx. Do tego pliku są również dodawane serializowane dane strefy czasowej.
Pola klucza (lub nazwy) zasobów nie powinny zawierać osadzonych spacji. Metoda jest wywoływana Replace(String, String) w celu usunięcia wszystkich osadzonych przestrzeni w identyfikatorach strefy czasowej, zanim zostaną przypisane do pliku zasobu.
Kompilowanie kodu
Ten przykład wymaga:
To odwołanie do System.Windows.Forms.dll i System.Core.dll należy dodać do projektu.
Aby zaimportować następujące przestrzenie nazw:
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Windows.Forms;
Imports System.Globalization Imports System.IO Imports System.Reflection Imports System.Resources