1

.NET Web サービス
JSON 形式の DateTime を返す .NET Web サービスがあります。Microsoft によって指定されたDateTime
json表現は、たとえば次のとおりです
。記号の後には、現地時間から GMT までのタイム ゾーン オフセットが表示されます。したがって、このシリアル化では、DateTime 値を Web サービスのローカル時間から UTC に変換する必要があります。

Android (java) クライアント
Web サービスの結果を受け取る Android アプリケーションで、Gson を使用して json を解析します。.NET DateTime json シリアル化は標準ではないため (Microsoft によると、DateTime にはそのような標準はありません)、gson はそのようなフォーマットされた日付を解析できません。クライアント側でシリアル化と逆シリアル化を行う Date TypeAdapter を作成しました。

したがって、これはうまくいくようです。UTC でのサービスとの間の DateTime 交換。ローカル時間から UTC 時間への変換に関して、.NET の DateTime と Java の Calendar がまったく同じ規則を考慮していれば問題ありません。

例:スイスには 1979 年から DST (夏時間) があります。Java は、DST が以前には存在しなかったことを認識しています。.NET は、以前から存在していると想定しています。そのため、1979 年より前の夏の日付を .NET から UTC に変換し、Java から現地時間に (プレゼンテーションのために) 戻すと、この日付は同じタイム ゾーンで 1 時間を失います。

質問 その問題にどう向き合うか?説明されているデータ交換で私がやっている間違いはありますか。さまざまな解決策を考えました。私が適切に動作すると想像できる唯一の方法は、.NET json DateTime シリアライゼーション/デシリアライゼーションを置き換えることです。もちろん、これは好ましいものではありません...

御時間ありがとうございます。

4

1 に答える 1

3

標準の.NETJsonシリアライザーを使用しないでください。Javaと.NETの間で作業している場合、必要以上に多くの頭痛の種が発生します。ご存知のように、Microsoftはほとんどの人が使用しない形式を使用しています。

最高のシリアライザーは、NewtonsoftのJson.NETNuGetページ)であり、.NET開発者のデファクトスタンダードになっています。それらには、使いやすい優れたDateTimeシリアル化/逆シリアル化オプションがあります。 詳細については、DateTimeのブログ投稿をご覧ください。私は、Json.NETv4.5のデフォルト形式であるISO8601を使用する傾向があります。

私は以前、Jsonを介してさまざまな言語で作成されたさまざまな製品と通信するエンタープライズアプリケーションに取り組んでいましたが、Json.NETはその製品間の通信を簡単にしました。

スイスのDateTimeの取り扱いに関する最新情報

一般的な中央ヨーロッパ標準時を指定しているため、.NETはスイスの日時ルールが具体的に何であるかを認識していません。スイスに対処するには、.NETにスイスのルールを与える必要があります。ウィキペディアを見ると、1981年に開始されたため、カスタムの作成TimeZoneInfoは次のようになります。

// UTC Time
var date1 = new DateTime(1969, 4, 20, 2, 20,00, DateTimeKind.Utc);
Console.WriteLine("Date 1: " + date1.ToString() + " - " + date1.IsDaylightSavingTime());

// CEST
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var date2 = TimeZoneInfo.ConvertTimeFromUtc(date1, timezone);
Console.WriteLine("Date 2: " + date2.ToString() + " - " + date2.IsDaylightSavingTime() + " " + timezone.IsAmbiguousTime(date2));

// Switzerland
var cesAdjRule = timezone.GetAdjustmentRules().Single();
var switzerlandStartTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
        cesAdjRule.DaylightTransitionStart.TimeOfDay,
        cesAdjRule.DaylightTransitionStart.Month, cesAdjRule.DaylightTransitionStart.Week,
        cesAdjRule.DaylightTransitionStart.DayOfWeek
);
var switzerlandAdjustmentRule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
    new DateTime(1981, 1, 1),
    DateTime.MaxValue.Date,
    cesAdjRule.DaylightDelta,
    switzerlandStartTransition,
    cesAdjRule.DaylightTransitionEnd
);
TimeZoneInfo.AdjustmentRule[] adjustments = {switzerlandAdjustmentRule};

var switzerlandTimeZone = TimeZoneInfo.CreateCustomTimeZone("Switzerland",
                                                            timezone.BaseUtcOffset,
                                                            "Switzerland",
                                                            "Switzerland",
                                                            "Switzerland",
                                                            adjustments, false);

var date3 = TimeZoneInfo.ConvertTimeFromUtc(date, timezone, switzerlandTimeZone);
Console.WriteLine("Date 3: " + date3.ToString() + " - " + date3.IsDaylightSavingTime() + " " + timezone.IsAmbiguousTime(date3));

その出力は次のようになります(少なくとも私のマシンでは):

Date 1: 4/20/1969 2:20:00 AM - False
Date 2: 4/20/1969 4:20:00 AM - True - False
Date 3: 4/20/1969 3:20:00 AM - True - False

ご覧のとおり、IsDaylightSavingsTimeはでTrueですがDateTimeTimeZoneInfo正しく変換されています。他のいくつかの組み合わせを試してみることも良さそうです。また、自分が持っていると思われるCESTとスイスの間で変換することもできますTimeZoneInfo.CovertTime()

于 2012-04-20T14:00:20.423 に答える