我有一个字符串,末尾为gmt日期值和-06:00。将其转换为CST的最佳方式是什么?我看了其他问题,但没有一个在06:00结束时回答我的问题。
这是我尝试过的,它错误为java.text.ParseException:无法解析的日期:"2015-02-19T11:50:09.5953377-06:00"
private DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSSSSS'Z'");
private DateFormat gmtFormat = new SimpleDateFormat();
private TimeZone cstTime = TimeZone.getTimeZone("CST");
gmtFormat.setTimeZone(cstTime);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
System.out.println("cst start date is " + gmtFormat.format("2015-02-19T11:50:09.5953377-06:00"));
} catch (ParseException e) {
e.printStackTrace();
}
我以前也遇到过类似的问题,实际上我用3种不同的iso格式获取日期,对此我感到非常沮丧……这不太好,但它可能有助于为你指明正确的方向。。。
我得到信息的3种格式:
private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
private static final String ISO_FORMAT2 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final String ISO_FORMAT3 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
实际上,试图解析它们(不必事先弄清楚正确的类型,在所有3个都失败的情况下返回一个新的日期对象,这样就不会因为该死的日期格式异常而崩溃):
public static Date parseIso(String date){
SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return sdf.parse(date);
}
catch (ParseException e) {
Log.g(TAG, "Failed 1st date parse with " + ISO_FORMAT + " for " + date);
sdf = new SimpleDateFormat(ISO_FORMAT2, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return sdf.parse(date);
}
catch (ParseException e2) {
Log.g(TAG, "Failed 2nd date parse with " + ISO_FORMAT2 + " for " + date);
sdf = new SimpleDateFormat(ISO_FORMAT3, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return sdf.parse(date);
}
catch (ParseException e3) {
Log.g(TAG, "Failed 3rd date parse with " + ISO_FORMAT3 + " for " + date);
}
}
}
return new Date();
}
然后将该日期实际转换为本地化日期:
public static String format(long mils, String format){
return format(getInstance(mils), format);
}
public static String format(Calendar calendar, String format){
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(new Date(calendar.getTime().getTime() + TimeZone.getDefault().getOffset(new Date().getTime())));
}
public static Calendar getInstance(long timeInMils){
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(timeInMils);
return cal;
}
所以现在你基本上可以调用
CalendarHelper.format(myDateObject.getTime(), "MMM dd, yyyy");
它将从您收到的原始UTC日期返回本地化的格式化日期。
同样,这并不漂亮,但我希望这能为您在UTC和客户时区之间转换指明正确的方向。祝你好运~
PS。我认为ISO_FORMAT_3将真正帮助您。我想我可能会从这些信息开始,但我不是一个聪明的人。
ISO 8601
您似乎误解了输入字符串2015-02-19T11:50:09.5953377-06:00
的含义。您没有"gmt日期值"。
该格式似乎是标准ISO 8601格式。
- 中间的CCD_ 2将日期部分与一天中的时间部分分离
- 末尾的
-06:00
是UTC的偏移量。意思是"此处显示的日期-时间值比UTC晚6小时"
CST
因此,如果你所说的CST
是指中央时区(美洲大陆中部的一些地区),那么你不需要进行转换。时间为11:50的字符串表示"伊利诺伊州、阿肯色州和路易斯安那州几乎是中午"。如果您将6小时添加到11:50,您将了解到同一时刻的UTC(GMT)日期时间:同一日期的17:50。
避免3-4个字母代码
顺便说一句,避免使用三个或四个字母的时区代码,如"CST"。这些代码既不是标准化的,也不是唯一的。存在许多重复项。例如,以CST
:为例
- 中部标准时间(美洲)
- 中国标准时间
- 中央标准时间(澳大利亚)
- 中夏时间(澳大利亚)
- 古巴标准时间
而是使用适当的时区。其中大多数是大陆加上斜线加上城市/地区。示例:America/Regina
、America/Monterrey
和America/Indiana/Knox
。
Joda时间|java.Time
java.util.Date/.Calendar类是出了名的麻烦。避开他们。
使用JodaTime库或Java8中内置的新java.Time包。java.time包的灵感来自Joda time,但经过了重新设计。每个人都有自己的长处和短处。
JodaTime和java.Time都使用ISO8601格式作为默认格式,用于解析和生成日期-时间值的字符串表示。
由于这个问题实际上是重复的,已经发布了数百个这样的问题和答案,我只举一个简单的例子。
String input = "2015-02-19T11:50:09.5953377-06:00";
DateTimeZone zoneAmerica_Regina = DateTimeZone.forID( "America/Regina" );
DateTime dateTimeAmericaRegina = new DateTime( input, zoneAmerica_Regina );
DateTime dateTimeLosAngeles = dateTimeAmericaRegina.withZone( DateTimeZone.forID( "America/Los_Angeles" ) );
DateTime dateTimeUtc = dateTimeAmericaRegina.withZone( DateTimeZone.UTC );
小数秒
您的输入字符串只有很小的一秒钟。JodaTime(类似java.util.Date)只处理毫秒分辨率——小数点后三位。java.item包处理纳秒分辨率。有些系统使用微秒分辨率,例如Postgres之类的数据库。有些系统遵循旧的Unix约定,即整秒。