سؤال

أنا أعمل مع خدمات الويب، وأقوم بإدراج السجلات التي تُرجع قيمة طابع زمني بنوع XMLGregorianCalendar.أحتاج إلى تحويلها إلى قيمة java.sql.Timestamp، لذلك أستخدم دالة مثل هذه.

public static java.sql.Timestamp getSqlTimeStamp(XMLGregorianCalendar xgc) {
    if (xgc == null) {
        return null;
    } else {
        return new Timestamp(xgc.toGregorianCalendar().getTime().getTime());
    }
}
Timestamp timestamp=getSqlTimeStamp(ExitInXMLGregor.getTimestamp());

مشكلتي هي أن قيمة الطابع الزمني في الخادم عندما أقوم بإدراج سجل تبدو كما يلي:10/03/2012 19:23:22

ولكن عندما أقوم بتحويل النوع، أحصل على قيمة الطابع الزمني كما يلي:10/03/2012 17:23:22

الوقت في الخادم (حيث توجد خدمة الويب) يزيد بساعتين عن الإعدادات المحلية الخاصة بي، ولسبب ما، أحصل على وقت الإدخال المحلي الخاص بي، بعد تحويله.المشكلة هي أنني بحاجة حقًا إلى الحصول على وقت الخادم، لأن قيمة الطابع الزمني في قاعدة البيانات تتطابق مع الخادم، وأواجه مشكلات في عملية التحديث، بسبب اختلاف قيم الطابع الزمني.

من فضلك، سأكون ممتنا لأي نوع من المساعدة.شكرًا!

يحرر:أجد حلاً نوعًا ما، لكنه ليس بالضبط ما أحتاجه.عندما أقوم بتحويل الطابع الزمني الخاص بي بتنسيق java.sql.Timestamp إلى XMLGregorian، أقوم بتعيين المنطقة الزمنية للخادم (setTimeZone(TimeZone.getTimeZone("GMT+02:00"))).هذا يعمل بالفعل، ولكنه بعيد عن الحل المثالي (قد يحدث أن تتغير المنطقة الزمنية أو حتى الخادم). سيكون من الرائع معرفة المنطقة الزمنية للخادم في هذه المرحلة ديناميكيًا، لكنني لا أعرف كيف.. .

public static XMLGregorianCalendar getXMLGregorianCalendar(Timestamp timestamp)
        throws BaseException {
    try {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
        gc.setTimeInMillis(timestamp.getTime());
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    } catch (DatatypeConfigurationException ex) {
        throw new BaseException(ex);
    }
}
هل كانت مفيدة؟

المحلول

أظن أن الطابع الزمني يحدد الوقت الصحيح، فقط لا يعرض مع المنطقة الزمنية المناسبة. 2012-10-03T17: 23: 22.342 هو نفسه 2012-10-03T19: 23: 22.342 + 02: 00، على افتراض المنطقة الزمنية (المخفية) السابقة +00: 00.

نصائح أخرى

ليرة تركية ؛ د

  • تمثل كلا السلسلتين نفس اللحظة، وتم تعديلهما ببساطة حسب المنطقة الزمنية مع الفشل في ملاحظة إزاحة من التوقيت العالمي المنسق (UTC)..
  • تجنب هذا الارتباك من خلال تضمين معلومات الإزاحة والمنطقة دائمًا في مثل هذه السلاسل.
  • استخدام الحديث java.time الفئات التي تحل محل الفئات القديمة المزعجة.(Instant, ، لا Timestamp)

رمز المثال.

myPreparedStatement.setObject( 
    … , 
    myXMLGregorianCalendar  // If forced to work with a `javax.xml.datatype.XMLGregorianCalendar` object rather than a modern java.time class…
    .toGregorianCalendar()  // …convert to a `java.util.GregorianCalendar`, and then…
    .toZonedDateTime()      // …convert to modern `java.time.ZonedDateTime` class.
    .toInstant()            // Adjust to UTC by extracting an `Instant` object.
)

الاسترجاع من قاعدة البيانات، اعتبارًا من JDBC 4.2 والإصدارات الأحدث.

Instant instant = myResultSet.getObject( … , Instant.class ) ;

java.time

كما الإجابة الصحيحة المقبولة من روبرت توبيلو شنيك يقول، يبدو أن كل شيء على ما يرام حيث تمثل كلا السلسلتين نفس اللحظة ولكن تم تعديلهما في منطقة زمنية مختلفة مع إزاحة مختلفة عن التوقيت العالمي المنسق (UTC).تكمن المشكلة في أن إحدى هاتين السلسلتين تفتقر إلى مؤشر الإزاحة من التوقيت العالمي المنسق (UTC).

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

العمل بالتوقيت العالمي المنسق

العمل بالتوقيت العالمي المنسق (UTC) يتجنب هذا النوع من الارتباك.من الأفضل بشكل عام تشغيل قيم التاريخ والوقت وتخزينها وتبادلها بالتوقيت العالمي المنسق (UTC).اضبط من التوقيت العالمي المنسق (UTC) إلى منطقة زمنية فقط للعرض التقديمي للمستخدم أو حيثما يتطلب ذلك منطق العمل.

أيضًا، أنت تستخدم فئات قديمة مزعجة للغاية والتي تم استبدالها الآن بـ java.time الطبقات.تحويل الخاص بك XMLGregorianCalendar ل java.time.ZonedDateTime.

ZonedDateTime zdt = myXMLGregorianCalendar.toGregorianCalendar().toZonedDateTime() ;

اضبط على التوقيت العالمي المنسق (UTC) عن طريق استخراج ملف Instant هدف.

Instant instant = zdt.toInstant() ;

اعتبارًا من JDBC 4.2 والإصدارات الأحدث، يمكنك التبادل مباشرة java.time الكائنات مع قاعدة البيانات.لا حاجة لاستخدام الإرث على الإطلاق java.sql.Timestamp الصف مرة أخرى.

myPreparedStatement.setObject( … , instant ) ;

استرجاع:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

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

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

يتحول

إذا كان يجب عليك التفاعل مع بعض التعليمات البرمجية القديمة التي تتطلب ملف java.sql.Timestamp, ، يمكنك التحويل ذهابًا وإيابًا باستخدام java.time.Instant.استدعاء طرق التحويل الجديدة المضافة إلى الفئات القديمة.

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;

الذهاب في الاتجاه الآخر.

Instant instant = ts.toInstant() ;

أنظر أيضا إجابتي إلى سؤال مماثل.


عن java.time

ال java.time إطار العمل مدمج في Java 8 والإصدارات الأحدث.تحل هذه الفئات محل الفئات القديمة المزعجة إرث فئات التاريخ والوقت مثل java.util.Date, Calendar, & SimpleDateFormat.

ال جودا تايم المشروع، الآن في نمط الصيانة, ، ينصح بالهجرة إلى java.time الطبقات.

لمعرفة المزيد، راجع أوراكل البرنامج التعليمي.وابحث في Stack Overflow عن العديد من الأمثلة والشروحات.المواصفات هي جي إس آر 310.

يمكنك التبادل java.time الكائنات مباشرة مع قاعدة البيانات الخاصة بك.إستخدم سائق JDBC متوافق مع جي دي بي سي 4.2 أو لاحقا.لا حاجة للسلاسل، لا حاجة ل java.sql.* الطبقات.

أين يمكن الحصول على دروس Java.time؟

ال ثلاثة عشرة اضافية يقوم المشروع بتوسيع Java.time بفئات إضافية.يعد هذا المشروع بمثابة أرض اختبار للإضافات المستقبلية المحتملة إلى java.time.قد تجد بعض الفئات المفيدة هنا مثل Interval, YearWeek, YearQuarter, ، و أكثر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top