Java 将日期字符串解析为日期并将其转换为毫秒后,输出时间总是低于两小时
我试图将带有日期的Java 将日期字符串解析为日期并将其转换为毫秒后,输出时间总是低于两小时,java,android,date,datetime,Java,Android,Date,Datetime,我试图将带有日期的字符串解析为日期对象,然后将其转换为毫秒 但无论我在做什么,输出结果(毫秒)总是比输入日期在2小时内低 例如,如果输入日期为2018-1-10 11:30,则输出日期为2018-01-10 9:30 这是我的代码: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String dateString = "2018-1-10 11:30"; Date resultDate = sdf.parse(d
字符串
解析为日期
对象,然后将其转换为毫秒
但无论我在做什么,输出结果(毫秒)总是比输入日期在2小时内低
例如,如果输入日期为2018-1-10 11:30,则输出日期为2018-01-10 9:30
这是我的代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String dateString = "2018-1-10 11:30";
Date resultDate = sdf.parse(dateString);
long millis = resultDate.getTime();
// millis = 1515576600000
// When i am trying to convert millis to normal date via online
// converters i am always getting
// this result 10.01.18 9:30
我无法理解为什么会发生这种情况。如何在转换毫秒后返回有效结果?为什么我在两个小时内得到这个差异?通过解析字符串,可以假定给定的时间基于您的本地时间,而日期是UTC。如果未指定时区,SimpleDataFormat将使用PC时区为您进行转换 要将其转换回,应使用
新日期(毫秒)
这也考虑了您的时区,您的结果应该是正确的。这看起来像是时区问题 检查您所在的时区。如果您在UTC+02:00,结果很好 如果要手动设置时区以与UTC相匹配(无偏移),请选中此堆栈溢出问题:
我希望这能对您有所帮助:)又一个例子,说明现代java日期和时间API
java.time
的优越之处。它强制您为此类操作指定区域偏移或时区,从而解决了问题:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-M-d H:mm");
String dateString = "2018-1-10 11:30";
long epochMillis = LocalDateTime.parse(dateString, dtf)
.atOffset(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
结果是1515583800000(可能更容易阅读为1515583800000)。删除要转换为秒的最后三个零,然后输入它们,例如。结果是:
2018年1月10日星期三11:30:00 GMT
<> P GMT最后确认时间在预期偏移(现在我们可以考虑GMT和UTC等效)。
问题:我可以在Android上使用java.time
?
你当然可以(不过我自己还没有这方面的经验)
- 对于一般的Android市场,使用Android版本的ThreeTen Backport(如下所述)。它叫ThreeTenABP。然后导入
和org.threeten.bp.format.DateTimeFormatter
org.threeten.bp.LocalDateTime
- 对于使用Java 8的较新Android设备,如果导入
和Java.time.format.DateTimeFormatter
,它应该可以开箱即用Java.time.LocalDateTime
- 在Java8和更高版本中,新的API是内置的
- 在Java6和Java7中,获取三个后端口,即新类的后端口(三个用于JSR310)
- ,解释如何使用
java.time
- ,Android版Three Ten Backport
- ,解释得非常透彻
- ,其中首次描述了现代日期和时间API
public class DateHelper {
/*///////////////////////////////////////////////////////////////
// MEMBERS
*////////////////////////////////////////////////////////////////
public static SimpleDateFormat MY_APPS_CUSTOM_FORMATTER;
public final static String MMMM_dd = "MMMM, dd";
public final static String MMM_dd_yyyy = "MMM dd yyyy";
public final static String MMSlashddSlashyy = "MM/dd/yy";
public final static String MMSlashddSlashyy_hhColonmm_a = "MM/dd/yy hh:mm a";
public final static Calendar mCalender = Calendar.getInstance();
public final static TimeZone mLocalTimezone = mCalender.getTimeZone();
/*///////////////////////////////////////////////////////////////
// PROPERTIES
*////////////////////////////////////////////////////////////////
public synchronized static SimpleDateFormat getMyAppsDateCustomFormatter(boolean toServer, String format){
MY_APPS_CUSTOM_FORMATTER = new SimpleDateFormat(format);
if(toServer){
MY_APPS_CUSTOM_FORMATTER.setTimeZone(TimeZone.getTimeZone("UTC"));
}else{
MY_APPS_CUSTOM_FORMATTER.setTimeZone(mLocalTimezone);
}
return MY_APPS_CUSTOM_FORMATTER;
}
/*///////////////////////////////////////////////////////////////
// EXTRA HELPER METHODS
*////////////////////////////////////////////////////////////////
public static String getNowLocalTime(String formatToReturn){
return getMyAppsDateCustomFormatter(false, formatToReturn).format(new Date());
}
/*///////////////////////////////////////////////////////////////
// FROM SERVER FORMATTING
*////////////////////////////////////////////////////////////////
public static String getLocalDateStringFromGMTLong(long gmtTimestamp, String formatToReturn){
return getMyAppsDateCustomFormatter(false, formatToReturn).format(new Date(gmtTimestamp * 1000));
}
public static Date getDateFromLocalFormattedString(String date, String formatToUse, boolean toServer) throws Exception{
Date parsedDate = null;
try {
parsedDate = getMyAppsDateCustomFormatter(toServer, formatToUse).parse(date);
} catch (ParseException e) { //developer error, do NOT localize
throw new Exception(Globals.DEV_ERROR_STRINGS.INVALID_DATE_SUPPLIED_FOR_DEFAULT_FORMATTER);
}
return parsedDate;
}
public static String getFormattedStringFromLocalDate(Date date, String formatToUse) throws Exception{
return getMyAppsDateCustomFormatter(false, formatToUse).format(date);
}
/*///////////////////////////////////////////////////////////////
// TO SERVER FORMATTING
*////////////////////////////////////////////////////////////////
public static long getGMTLongFromLocalDate(Date date){
//Get Local Timezone
TimeZone tz = TimeZone.getDefault();
//Create new date for offset to GMT
Date ret = new Date(date.getTime() - tz.getRawOffset() );
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if ( tz.inDaylightTime( ret )){
Date dstDate = new Date( ret.getTime() - tz.getDSTSavings() );
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if ( tz.inDaylightTime( dstDate )){
ret = dstDate;
}
}
return ret.getTime();
}
public static long getGMTLongFromLocalDateString(String date, String formatUsed) throws Exception {
Date passedDate = getDateFromLocalFormattedString(date, formatUsed, true);
//Get Local Timezone
TimeZone tz = TimeZone.getDefault();
//Create new date for offset to GMT
Date ret = new Date(passedDate.getTime() - tz.getRawOffset() );
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if ( tz.inDaylightTime( ret )){
Date dstDate = new Date( ret.getTime() - tz.getDSTSavings() );
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if ( tz.inDaylightTime( dstDate )){
ret = dstDate;
}
}
return ret.getTime() / 1000;
}
public static long getNowGMTTime(){
return getGMTLongFromLocalDate(new Date());
}
}
希望这对您有所帮助,您可以复制和粘贴这个类,并在服务器之间处理许多日期格式和时区问题
public class DateHelper {
/*///////////////////////////////////////////////////////////////
// MEMBERS
*////////////////////////////////////////////////////////////////
public static SimpleDateFormat MY_APPS_CUSTOM_FORMATTER;
public final static String MMMM_dd = "MMMM, dd";
public final static String MMM_dd_yyyy = "MMM dd yyyy";
public final static String MMSlashddSlashyy = "MM/dd/yy";
public final static String MMSlashddSlashyy_hhColonmm_a = "MM/dd/yy hh:mm a";
public final static Calendar mCalender = Calendar.getInstance();
public final static TimeZone mLocalTimezone = mCalender.getTimeZone();
/*///////////////////////////////////////////////////////////////
// PROPERTIES
*////////////////////////////////////////////////////////////////
public synchronized static SimpleDateFormat getMyAppsDateCustomFormatter(boolean toServer, String format){
MY_APPS_CUSTOM_FORMATTER = new SimpleDateFormat(format);
if(toServer){
MY_APPS_CUSTOM_FORMATTER.setTimeZone(TimeZone.getTimeZone("UTC"));
}else{
MY_APPS_CUSTOM_FORMATTER.setTimeZone(mLocalTimezone);
}
return MY_APPS_CUSTOM_FORMATTER;
}
/*///////////////////////////////////////////////////////////////
// EXTRA HELPER METHODS
*////////////////////////////////////////////////////////////////
public static String getNowLocalTime(String formatToReturn){
return getMyAppsDateCustomFormatter(false, formatToReturn).format(new Date());
}
/*///////////////////////////////////////////////////////////////
// FROM SERVER FORMATTING
*////////////////////////////////////////////////////////////////
public static String getLocalDateStringFromGMTLong(long gmtTimestamp, String formatToReturn){
return getMyAppsDateCustomFormatter(false, formatToReturn).format(new Date(gmtTimestamp * 1000));
}
public static Date getDateFromLocalFormattedString(String date, String formatToUse, boolean toServer) throws Exception{
Date parsedDate = null;
try {
parsedDate = getMyAppsDateCustomFormatter(toServer, formatToUse).parse(date);
} catch (ParseException e) { //developer error, do NOT localize
throw new Exception(Globals.DEV_ERROR_STRINGS.INVALID_DATE_SUPPLIED_FOR_DEFAULT_FORMATTER);
}
return parsedDate;
}
public static String getFormattedStringFromLocalDate(Date date, String formatToUse) throws Exception{
return getMyAppsDateCustomFormatter(false, formatToUse).format(date);
}
/*///////////////////////////////////////////////////////////////
// TO SERVER FORMATTING
*////////////////////////////////////////////////////////////////
public static long getGMTLongFromLocalDate(Date date){
//Get Local Timezone
TimeZone tz = TimeZone.getDefault();
//Create new date for offset to GMT
Date ret = new Date(date.getTime() - tz.getRawOffset() );
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if ( tz.inDaylightTime( ret )){
Date dstDate = new Date( ret.getTime() - tz.getDSTSavings() );
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if ( tz.inDaylightTime( dstDate )){
ret = dstDate;
}
}
return ret.getTime();
}
public static long getGMTLongFromLocalDateString(String date, String formatUsed) throws Exception {
Date passedDate = getDateFromLocalFormattedString(date, formatUsed, true);
//Get Local Timezone
TimeZone tz = TimeZone.getDefault();
//Create new date for offset to GMT
Date ret = new Date(passedDate.getTime() - tz.getRawOffset() );
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if ( tz.inDaylightTime( ret )){
Date dstDate = new Date( ret.getTime() - tz.getDSTSavings() );
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if ( tz.inDaylightTime( dstDate )){
ret = dstDate;
}
}
return ret.getTime() / 1000;
}
public static long getNowGMTTime(){
return getGMTLongFromLocalDate(new Date());
}
}
这看起来像是时区问题。您在哪个时区?请提供您的代码和更多详细信息。我得到了正确的输出。此外,毫秒的值为1515564000000,这与您得到的不同时区是至关重要的。您需要指定在哪个时区解释您的11:30。给我:格林尼治时间:2018年1月10日星期三上午9:30:00。您的时区:2018年1月10日星期三上午10:30:00 GMT+01:00。如果你的11:30在区域偏移UTC+02:00,结果与它一致。作为一个旁白,考虑扔掉长期过时和臭名昭著的麻烦<代码> SimpleDateFormat <代码>和朋友,并添加到你的Android项目中,以便使用<代码> java.时间>代码>,java java日期和时间API。和我一起工作真是太好了。是的,我在UTC+02.00。对我来说,正确的时间是11点30分。但总是在把日期转换成毫秒后,我会得到9点30分。是否可以转换没有时区的日期以避免这些时间更改?只需按照我的答案中的链接“如何手动设置java.util.Date的时区?”即可获得问题的答案;-)谢谢,我会试试:-)谢谢你的帮助)在设置时区之后-如果最终得到结果谢谢,但是-DateTimeFormatter.of模式对我来说不是很合适,因为我的最小API级别是15((我不太确定,15级还不够,你可以使用,现代API(也称为JSR-310)的后端口)到Android?这里有更多:。在这种情况下,请确保从
org.threeten.bp
导入。向项目中添加threeten Backport和ThreetenABP库绝对值得。遗留日期-时间类是一个糟糕的烂摊子,应该避免。