سؤال

ونحن نتعامل مع أحد التطبيقات التي تحتاج لمعالجة البيانات في الوقت العالمية من مناطق زمنية مختلفة، وإعدادات الوقت الصيفي. والفكرة هي لتخزين كل شيء في تنسيق UTC داخليا وفقط تحويل ذهابا وإيابا لواجهات المستخدم المترجمة. لا توفر SQL خادم أي آليات للتعامل مع ترجمة إعطاء الوقت، بلد والتوقيت؟

ويجب أن يكون هذا مشكلة شائعة، لذلك أنا مندهش أن جوجل لا يحضر أي شيء قابل للاستخدام.

وأي مؤشرات؟

هل كانت مفيدة؟

المحلول

و7 سنوات مرت و...
في الواقع هناك هذا جديدة SQL خادم 2016 الميزة التي يفعل بالضبط ما تحتاجه.
ويطلق عليه في وقت ZONE وكان تحويل التاريخ إلى المنطقة الزمنية المحددة النظر DST (التوقيت الصيفي) التغييرات.
مزيد من المعلومات هنا: https://msdn.microsoft.com/en-us/library/mt612795.aspx

نصائح أخرى

وهذا يعمل على التواريخ التي لديها حاليا نفس UTC تعويض كمضيف SQL ملقم. أنه لا يأخذ في الحسبان التغييرات الصيفي. استبدال YOUR_DATE مع التاريخ المحلي لتحويل.

وSELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);

ورغم أن البعض من هذه الإجابات سوف تحصل في الملعب، لا يمكنك أن تفعل ما نحاول القيام به مع تواريخ تعسفية لسيكلسرفير 2005 وفي وقت سابق بسبب التوقيت الصيفي. وسوف تستخدم الفرق بين UTC المحلي والحاليين الحالي تعطيني تعويض كما هو قائم اليوم. لم أجد وسيلة لتحديد ما هي الإزاحة يمكن أن يكون للتاريخ المذكور.

وقال ذلك، وأنا أعلم أن SQLSERVER 2008 يوفر بعض وظائف التاريخ الجديدة التي يمكن أن تعالج هذه المسألة، ولكن يحتاج الناس باستخدام إصدار سابق ليكون على بينة من القيود.

ونهجنا هو أن تستمر UTC وإجراء تحويل على جانب العميل حيث لدينا المزيد من السيطرة على دقة التحويل و.

وSQL سيرفر 2008 لديه نوع يسمى datetimeoffset. انها مفيدة حقا لهذا النوع من الاشياء.

http://msdn.microsoft.com/en-us/library /bb630289.aspx

وبعد ذلك يمكنك استخدام SWITCHOFFSET وظيفة لنقلها من توقيت واحد إلى آخر، ولكن لا يزال الحفاظ على قيمة UTC نفسها.

http://msdn.microsoft.com/en-us/library /bb677244.aspx

وروب

ويمكنك استخدام مشروعي href="https://github.com/mj1856/SqlServerTimeZoneSupport"> SQL خادم المنطقة الزمنية دعم للتحويل بين مناطق زمنية قياسية IANA as المدرجة هنا .

وUTC إلى المحلي هو من هذا القبيل:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')

والمحلية إلى UTC مثل هذا:

SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)

والخيارات الرقمية هي العلم للسيطرة على السلوك عندما تتأثر القيم الزمنية المحلية من التوقيت الصيفي. يتم وصف هذه بالتفصيل في وثائق المشروع.

وهنا هو رمز لتحويل DateTime منطقة واحدة لDateTime منطقة أخرى

DECLARE @UTCDateTime DATETIME = GETUTCDATE();
DECLARE @ConvertedZoneDateTime DATETIME;

-- 'UTC' to 'India Standard Time' DATETIME
SET @ConvertedZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time'
SELECT @UTCDateTime AS UTCDATE,@ConvertedZoneDateTime AS IndiaStandardTime

-- 'India Standard Time' to 'UTC' DATETIME
SET @UTCDateTime = @ConvertedZoneDateTime AT TIME ZONE 'India Standard Time' AT TIME ZONE 'UTC'
SELECT @ConvertedZoneDateTime AS IndiaStandardTime,@UTCDateTime AS UTCDATE

ملاحظة : AT TIME ZONE على يعمل فقط على SQL Server 2016 + و ميزة هو أنه تلقائيا ترى ضوء النهار عند تحويل إلى منطقة زمنية معينة

وأنا أميل إلى تميل إلى استخدام DateTimeOffset لجميع تخزين التاريخ الوقت الذي لا علاقة لحدث محلي (أي: لقاء / حزب، الخ، 12:00 حتي 15:00 في المتحف)

لتحصل على DTO الحالي كما UTC:

DECLARE @utcNow DATETIMEOFFSET = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
DECLARE @utcToday DATE = CONVERT(DATE, @utcNow);
DECLARE @utcTomorrow DATE = DATEADD(D, 1, @utcNow);
SELECT  @utcToday [today]
        ,@utcTomorrow [tomorrow]
        ,@utcNow [utcNow]

ملحوظة: وسوف تستخدم دائما UTC عند إرسال عبر السلك ... JS العميل يمكن الحصول بسهولة من / UTC المحلي. انظر: new Date().toJSON() ...

وسوف JS التالية التعامل مع تحليل لUTC تاريخ / GMT في شكل ISO8601 إلى التاريخ والوقت المحلي.

if (typeof Date.fromISOString != 'function') {
  //method to handle conversion from an ISO-8601 style string to a Date object
  //  Date.fromISOString("2009-07-03T16:09:45Z")
  //    Fri Jul 03 2009 09:09:45 GMT-0700
  Date.fromISOString = function(input) {
    var date = new Date(input); //EcmaScript5 includes ISO-8601 style parsing
    if (!isNaN(date)) return date;

    //early shorting of invalid input
    if (typeof input !== "string" || input.length < 10 || input.length > 40) return null;

    var iso8601Format = /^(\d{4})-(\d{2})-(\d{2})((([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d{1,12}))?)?)?)?)?([Zz]|([-+])(\d{2})\:?(\d{2}))?$/;

    //normalize input
    var input = input.toString().replace(/^\s+/,'').replace(/\s+$/,'');

    if (!iso8601Format.test(input))
      return null; //invalid format

    var d = input.match(iso8601Format);
    var offset = 0;

    date = new Date(+d[1], +d[2]-1, +d[3], +d[7] || 0, +d[8] || 0, +d[10] || 0, Math.round(+("0." + (d[12] || 0)) * 1000));

    //use specified offset
    if (d[13] == 'Z') offset = 0-date.getTimezoneOffset();
    else if (d[13]) offset = ((parseInt(d[15],10) * 60) + (parseInt(d[16],10)) * ((d[14] == '-') ? 1 : -1)) - date.getTimezoneOffset();

    date.setTime(date.getTime() + (offset * 60000));

    if (date.getTime() <= new Date(-62135571600000).getTime()) // CLR DateTime.MinValue
      return null;

    return date;
  };
}

نعم، إلى حد ما كما هو مفصل <لأ href = "http://blogs.msdn.com/sqlprogrammability/archive/2008/03/18/using-time-zone-data-in-sql-server-2008 .aspx اتصال "يختلط =" نوفولو noreferrer "> هنا .
نهج لقد استعملت (قبل عام 2008) هو أن تفعل التحويل في ومنطق الأعمال. NET قبل إدراج في DB.

ويمكنك استخدام وظيفة GETUTCDATE () للحصول UTC التاريخ والوقت ربما يمكنك تحديد الفرق بين GETUTCDATE () وGETDATE () واستخدام هذا الاختلاف على ajust التواريخ إلى UTC

ولكن أنا أتفق مع الرسالة السابقة، أنه من الأسهل بكثير للسيطرة التاريخ والوقت المناسب في طبقة رجال الأعمال (في .NET، على سبيل المثال).

<ع> استخدام عينة:

SELECT
    Getdate=GETDATE()
    ,SysDateTimeOffset=SYSDATETIMEOFFSET()
    ,SWITCHOFFSET=SWITCHOFFSET(SYSDATETIMEOFFSET(),0)
    ,GetutcDate=GETUTCDATE()
GO

وإرجاع:

Getdate SysDateTimeOffset   SWITCHOFFSET    GetutcDate
2013-12-06 15:54:55.373 2013-12-06 15:54:55.3765498 -08:00  2013-12-06 23:54:55.3765498 +00:00  2013-12-06 23:54:55.373
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top