我的日期字符串为1/1/1970 8:00 AM
正确的millis应为8 hours * 60 minutes per hour * 60000 milliseconds per minute = 28800000
但是,使用Date.parse(dateString)
会返回50400000
我不理解什么?
修改
我最初尝试使用date.getTime();
这是我的原始代码:
SimpleDateFormat dateFmt = new SimpleDateFormat("MM/dd/yyyy h:mm a");
dateFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
StringBuilder sb = new StringBuilder();
sb.append(month).append("/");
sb.append(day).append("/");
sb.append(year).append(" ");
sb.append(pad(hour)).append(":");
sb.append(pad(minute)).append(" ");;
sb.append(ampm);
Date date = new Date();
date = dateFmt.parse(sb.toString());
date.getTime()
答案 0 :(得分:7)
这几乎肯定是问题所在:
如果未指定时区,则假定为本地时区。
我的猜测是你所处的时区是在Unix时代的UTC-6,所以当地时间早上8点是UTC时间下午2点。
然后,当有更好的替代方法(SimpleDateFormat
,允许您设置时区)可用时,使用弃用方法存在更基本的问题。不推荐使用原因的方法。你不应该只使用弃用的方法,否则你会继续遇到这样的事情。
事实上,如果可能的话,最好使用Joda Time - 但至少远离Date
中弃用的方法。
示例代码:
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy h:mm aa", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
long millis = format.parse(text).getTime();
您可能希望将dd/MM
更改为MM/dd
,具体取决于您的日期格式 - 我们无法从“01/01”判断出来。请注意时区和区域设置的显式设置。
答案 1 :(得分:1)
因为您当地的时区。使用带有时区的简单日期格式,如下所示,以获得UTC
时区所需的值:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
String dateS = "1/1/1970 8:00 AM";
format.setTimeZone(TimeZone.getTimeZone("UTC"));
format.setLenient(true);
Date date = format.parse(dateS);
System.out.println(date.getTime()); //<-- prints 28800000
或更紧凑:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = format.parse("1/1/1970 8:00 AM");
System.out.println(date.getTime()); //<-- prints 28800000
答案 2 :(得分:0)
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
另外,下面引用的是来自 home page of Joda-Time 的通知:
<块引用>请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。
java.time
(现代日期时间 API)的解决方案:您不需要形成字符串:您可以使用 LocalDateTime#of
创建 LocalDateTime
的实例,该实例可以按顺序转换为 Instant
获取 Unix 纪元的毫秒数。
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
int year = 1970, month = 1, dayOfMonth = 1, hour = 8, minute = 0;
LocalDateTime ldt = LocalDateTime.of(year, month, dayOfMonth, hour, minute);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
输出:
28800000
如果您已经有给定格式的日期时间字符串:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u h:m a", Locale.ENGLISH);
String strDateTime = "1/1/1970 8:00 AM";
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
输出:
28800000
从 Trail: Date Time 了解有关现代 Date-Time API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。