ฉันจำเป็นต้องบังคับให้การดำเนินการที่เกี่ยวข้องกับเวลาเป็น GMT / UTC โดยไม่คำนึงถึงเขตเวลาที่ตั้งไว้บนเครื่อง วิธีใดที่สะดวกในการเขียนโค้ด
เพื่อชี้แจงฉันใช้เวลาเซิร์ฟเวอร์ DB สำหรับการดำเนินการทั้งหมด แต่ออกมาในรูปแบบตามเขตเวลาท้องถิ่น
ขอบคุณ!
ฉันจำเป็นต้องบังคับให้การดำเนินการที่เกี่ยวข้องกับเวลาเป็น GMT / UTC โดยไม่คำนึงถึงเขตเวลาที่ตั้งไว้บนเครื่อง วิธีใดที่สะดวกในการเขียนโค้ด
เพื่อชี้แจงฉันใช้เวลาเซิร์ฟเวอร์ DB สำหรับการดำเนินการทั้งหมด แต่ออกมาในรูปแบบตามเขตเวลาท้องถิ่น
ขอบคุณ!
คำตอบ:
OP ตอบคำถามนี้เพื่อเปลี่ยนเขตเวลาเริ่มต้นสำหรับอินสแตนซ์เดียวของ JVM ที่รันตั้งค่าuser.timezone
คุณสมบัติระบบ:
java -Duser.timezone=GMT ... <main-class>
หากคุณต้องการตั้งค่าโซนเวลาเฉพาะเมื่อดึงอ็อบเจ็กต์ Date / Time / Timestamp จากฐานข้อมูลResultSet
ให้ใช้รูปแบบที่สองของgetXXX
วิธีการที่ใช้Calendar
วัตถุ:
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
Date dateValue = rs.getDate("DateColumn", tzCal);
// Other fields and calculations
}
หรือตั้งวันที่ใน PreparedStatement:
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();
สิ่งเหล่านี้จะช่วยให้แน่ใจว่าค่าที่จัดเก็บในฐานข้อมูลมีความสอดคล้องกันเมื่อคอลัมน์ฐานข้อมูลไม่เก็บข้อมูลเขตเวลา
java.util.Date
และjava.sql.Date
เรียนเก็บในเวลาจริง (มิลลิวินาที) ในเวลา UTC SimpleDateFormat
การจัดรูปแบบเหล่านี้ในการส่งออกไปยังเขตอื่นใช้ คุณยังสามารถเชื่อมโยงเขตเวลากับค่าโดยใช้วัตถุปฏิทิน:
TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);
ข้อมูลอ้างอิงที่เป็นประโยชน์
https://docs.oracle.com/javase/9/troubleshoot/time-zone-settings-jre.htm#JSTGD377
https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html
นอกจากนี้หากคุณสามารถกำหนดเขตเวลา JVM ด้วยวิธีนี้
System.setProperty("user.timezone", "EST");
หรือ-Duser.timezone=GMT
ในอาร์กิวเมนต์ JVM
System.setProperty("user.timezone" ...)
ไม่ทำงาน
ฉันต้องตั้งค่าเขตเวลา JVM สำหรับ Windows 2003 Server เพราะมันส่งคืน GMT สำหรับ Date () ใหม่เสมอ
-Duser.timezone=America/Los_Angeles
หรือเขตเวลาที่เหมาะสมของคุณ การค้นหารายการเขตเวลาพิสูจน์แล้วว่าเป็นเรื่องที่ท้าทายเช่นกัน ...
นี่คือสองรายการ;
http://wrapper.tanukisoftware.com/doc/english/prop-timezone.html
คุณสามารถเปลี่ยนเขตเวลาโดยใช้TimeZone.setDefault () :
TimeZone.setDefault(TimeZone.getTimeZone("GMT"))
สำหรับฉันเพียงแค่ SimpleDateFormat อย่างรวดเร็ว
private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd");
static {
GMT.setTimeZone(TimeZone.getTimeZone("GMT"));
SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
}
จากนั้นจัดรูปแบบวันที่ด้วยเขตเวลาที่ต่างกัน
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
ขอแนะนำให้คุณเขียนโค้ดทั้งหมดของคุณเพื่อระบุโซนเวลาที่ต้องการ / คาดหวังอย่างชัดเจน คุณไม่จำเป็นต้องขึ้นอยู่กับเขตเวลาเริ่มต้นปัจจุบันของ JVM และทราบว่าเขตเวลาเริ่มต้น JVM ปัจจุบันสามารถเปลี่ยนในช่วงเวลาใดช่วง Runtime ด้วยรหัสใด ๆ TimeZone.setDefault
ในหัวข้อของการโทร การโทรดังกล่าวส่งผลกระทบต่อแอปทั้งหมดภายใน JVM นั้นทันที
คำตอบอื่น ๆ บางคำตอบถูก แต่ตอนนี้ล้าสมัยแล้ว คลาสวันที่และเวลาที่แย่มากที่มาพร้อมกับ Java เวอร์ชันแรกสุดนั้นมีข้อบกพร่องซึ่งเขียนขึ้นโดยผู้ที่ไม่เข้าใจความซับซ้อนและรายละเอียดปลีกย่อยของการจัดการวันที่และเวลา
คลาสวันที่และเวลาดั้งเดิมถูกแทนที่ด้วยคลาสjava.time ที่กำหนดไว้ใน JSR 310
ZoneId
เพื่อเป็นตัวแทนของโซนเวลาการใช้งาน เพื่อเป็นตัวแทนชดเชยจากที่ UTC ZoneOffset
ใช้ ค่าชดเชยเป็นเพียงจำนวนชั่วโมงนาทีวินาทีข้างหน้าหรือหลังเส้นเมริเดียนไพรม์ เขตเวลามีมากขึ้น เขตเวลาคือประวัติศาสตร์ของการเปลี่ยนแปลงในอดีตปัจจุบันและอนาคตของค่าชดเชยที่ผู้คนในภูมิภาคหนึ่ง ๆ ใช้
ฉันต้องการบังคับให้การดำเนินการที่เกี่ยวข้องกับเวลา GMT / UTC
ZoneOffset.UTC
สำหรับการชดเชยของศูนย์ชั่วโมงนาทีวินาทีใช้อย่างต่อเนื่อง
Instant
ในการจับภาพช่วงเวลาปัจจุบันใน UTC ให้ใช้Instant
ไฟล์. คลาสนี้แสดงช่วงเวลาใน UTC โดยจะเป็น UTC ตามคำจำกัดความเสมอ
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime
หากต้องการดูช่วงเวลาเดียวกันผ่านเวลานาฬิกาแขวนที่ผู้คนในภูมิภาคใดภูมิภาคหนึ่งใช้ให้ปรับเป็นเขตเวลา ช่วงเวลาเดียวกันจุดเดียวกันบนไทม์ไลน์เวลานาฬิกาแขวนที่ต่างกัน
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
คุณพูดถึงฐานข้อมูล
ช่วงเวลาในการดึงข้อมูลจากฐานข้อมูลที่เป็นคอลัมน์ของคุณควรจะเป็นชนิดข้อมูลที่คล้ายกับ TIMESTAMP WITH TIME ZONE
SQL ดึงข้อมูลวัตถุแทนที่จะเป็นสตริง ใน JDBC 4.2 และใหม่กว่าเราสามารถแลกเปลี่ยนวัตถุjava.timeกับฐานข้อมูลได้ OffsetDateTime
ถูกต้องตาม JDBC ในขณะที่Instant
และZonedDateTime
เป็นตัวเลือก
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ในฐานข้อมูลและไดรเวอร์ส่วนใหญ่ฉันเดาว่าคุณจะได้รับช่วงเวลาดังที่เห็นใน UTC แต่ถ้าไม่คุณสามารถปรับได้สองวิธี:
Instant
: odt.toInstant()
java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date
, และCalendar
SimpleDateFormat
ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310
โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำให้ย้ายไปยังคลาสjava.time
คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่จำเป็นต้องมีสตริงไม่จำเป็นต้องมีjava.sql.*
คลาส
จะหาคลาส java.time ได้ที่ไหน?
ฉันจะดึงเวลาจาก DB ในรูปแบบดิบ (การประทับเวลาแบบยาวหรือวันที่ของจาวา) จากนั้นใช้ SimpleDateFormat เพื่อจัดรูปแบบหรือปฏิทินเพื่อจัดการ ในทั้งสองกรณีคุณควรกำหนดเขตเวลาของวัตถุก่อนใช้งาน
ดูSimpleDateFormat.setTimeZone(..)
และCalendar.setTimeZone(..)
รายละเอียด
ใช้คุณสมบัติของระบบ:
-Duser.timezone=UTC
สร้างคู่ของไคลเอนต์ / เซิร์ฟเวอร์เพื่อให้หลังจากการดำเนินการไคลเอนต์เซิร์ฟเวอร์จะส่งเวลาและวันที่ที่ถูกต้อง จากนั้นไคลเอนต์จะถามเซิร์ฟเวอร์ pm GMT และเซิร์ฟเวอร์จะส่งคำตอบกลับไปที่ถูกต้อง
ดำเนินการตามบรรทัดนี้ใน MySQL เพื่อรีเซ็ตเขตเวลาของคุณ:
SET @@global.time_zone = '+00:00';
ว้าว. ฉันรู้ว่านี่เป็นเธรดโบราณ แต่ทั้งหมดที่ฉันพูดได้คืออย่าเรียก TimeZone.setDefault () ในรหัสระดับผู้ใช้ใด ๆ สิ่งนี้จะกำหนดเขตเวลาสำหรับ JVM ทั้งหมดเสมอและเกือบจะเป็นความคิดที่แย่มาก เรียนรู้การใช้ไลบรารี joda.time หรือคลาส DateTime ใหม่ใน Java 8 ซึ่งคล้ายกับไลบรารี joda.time มาก
หวังว่าโค้ดด้านล่างจะช่วยคุณได้
DateFormat formatDate = new SimpleDateFormat(ISO_DATE_TIME_PATTERN);
formatDate.setTimeZone(TimeZone.getTimeZone("UTC"));
formatDate.parse(dateString);
หากคุณต้องการรับเวลา GMT ด้วย intiger เท่านั้น: var currentTime = new Date (); var currentYear = '2010' var currentMonth = 10; var currentDay = '30 'var currentHours = '20' var currentMinutes = '20 'var currentSeconds = '00' var currentMilliseconds = '00 '
currentTime.setFullYear(currentYear);
currentTime.setMonth((currentMonth-1)); //0is January
currentTime.setDate(currentDay);
currentTime.setHours(currentHours);
currentTime.setMinutes(currentMinutes);
currentTime.setSeconds(currentSeconds);
currentTime.setMilliseconds(currentMilliseconds);
var currentTimezone = currentTime.getTimezoneOffset();
currentTimezone = (currentTimezone/60) * -1;
var gmt ="";
if (currentTimezone !== 0) {
gmt += currentTimezone > 0 ? ' +' : ' ';
gmt += currentTimezone;
}
alert(gmt)