本文中,我们将展示如何在不同时区之间转换时间,我们分别使用Date、Calendar、Joda Time。
本例从新加坡时区
(GMT+8:00) Asia/Singapore - Singapore Time
Date : 22-1-2015 10:15:55 AM
转换到美国纽约时区
(GMT-5:00) America/NewYork - Eastern Standard Time
Date : 21-1-2015 09:15:55 PM
注意,在JDK1.7版本之前,java.util.Date没有时区的概念,Date对象只显示系统的时间和系统的默认时区。
1.使用Date
使用DateFormat格式化时间(需要设置时区)
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
sdfAmerica.setTimeZone(TimeZone.getTimeZone("America/NewYork"));
String sDateInAmerica = sdfAmerica.format(date);
完整的代码如下:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneTest {
public static void main(String[] argv) throws
ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// From TimeZone Asia/Singapore
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date : " + formatter.format(date));
// To TimeZone America/NewYork
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
TimeZone tzInAmerica = TimeZone.getTimeZone("America/NewYork");
sdfAmerica.setTimeZone(tzInAmerica);
String sDateInAmerica = sdfAmerica.format(date); // Convert to String first
Date dateInAmerica = formatter.parse(sDateInAmerica);
System.out.println("\nTimeZone : " + tzInAmerica.getID() +
" - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
System.out.println("Date (String) : " + sDateInAmerica);
System.out.println("Date (Object) : " + formatter.format(dateInAmerica));
}
}
输出结果为:
TimeZone : Asia/Singapore - Singapore Time
TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Singapore",offset=28800000,dstSavings=0,useDaylight=false,transitions=9,lastRule=null]
Date : 22-1-2015 10:15:55 AM
TimeZone : America/NewYork - Eastern Standard Time
TimeZone : sun.util.calendar.ZoneInfo[id="America/NewYork",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/NewYork,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
Date (String) : 21-1-2015 09:15:55 PM
Date (Object) : 21-1-2015 09:15:55 PM
2.使用Calendar
Calendar设置时区
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.setTimeZone(tzInAmerica);
我们经常犯的错误是这样获取java.util.Date.
Date dateInAmerican = calendar.getTime();
在以上得例子,不管Calendar的时区如何设置,Date总是显示的时本地的系统时间22-1-2015 10:15:55 AM.
正确得方式是需要使用DateFormat来格式化。
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
TimeZone tzInAmerica = TimeZone.getTimeZone("America/NewYork");
sdfAmerica.format(calendar.getTime())
或者是使用一种calendar.get()的方法获取。
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAYOFMONTH);
int hour = calendar.get(Calendar.HOUR); // 12 hour clock
int hourOfDay = calendar.get(Calendar.HOUROFDAY); // 24 hour clock
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int ampm = calendar.get(Calendar.AMPM); //0 = AM , 1 = PM
3.使用Joda Time
JodaTime设置时区
DateTime dt = new DateTime(date);
DateTimeZone dtZone = DateTimeZone.forID("America/NewYork");
DateTime dtus = dt.withZone(dtZone);
也是容易饭的错误是,直接转换为java.util.Date,时区的信息将丢失。
//Output : 22-1-2015 10:15:55 AM
Date dateInAmerica = dtus.toDate();
正确得方式是转换为Joda得LocalDateTime
//Output : 21-1-2015 09:15:55 PM
Date dateInAmerica = dtus.toLocalDateTime().toDate();
参考:
Date and Time Manipulation in Java Using JodaTime
SimpledateFormat JavaDoc
World Time Server