Java 中的日期到日转换
我可以使用下面的代码将日期转换为天数。
SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd");
String s1 = sfd.format(dateObj);
String a1 [] = s1.split("-");
int year = Integer.parseInt(a1[0].toString());
int month = Integer.parseInt(a1[1])-1;
int day = Integer.parseInt((a1[2]));
Calendar c1 = Calendar.getInstance();
c1.set(year,month,day);
days = c1.getTime().getTime()/(24*60*60*1000);
上面的代码在我的系统(时区 GMT +5.30 的 Windows)中准确运行。
然而,当系统中的时间为 20:00 时,EST 或太平洋时区中的相同代码会在最终结果中添加一天 1。
可能是什么问题?
我们需要在代码中明确设置时区吗?
输入日期不包含任何时间戳..
存储在 java.util.Date
而不是 java.sql.Date
中是否正确?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编辑:根据亚历克斯的评论,你的代码开头的问题可能让我看不到你的真正目标。
Date
表示时间的一个瞬间。根据时区的不同,该日期可能会发生在不同的日期,但您希望这会如何影响事情呢?您想要自 Unix 纪元(始终为 UTC)以来的天数还是自 1970 年 1 月 1 日以来特定时区的天数?为什么您需要这个“天数”而不是诸如LocalDate
之类的日期表示形式?这里有什么用例?编辑:如果您只想知道自 Unix 纪元以来的天数,您可以跳过大部分内容:
您根本不应该仅仅为了获取年/月/日而进行格式化。只需创建一个
Calendar
,设置相关时区,使用已有的dateObj
调用setTime
,然后清除小时/分钟/日历的第二部分。但是,您应该明确指定要考虑的时区 -
Date
表示时间上的瞬间,这意味着不同时区的不同日期。您还应该考虑使用 Joda Time 它使所有这些变得更简单并且具有特定的日期类型(
本地日期
)。这也使得您可以轻松找到 Unix 纪元和特定日期之间的天数,而无需自己执行除法。EDIT: As per Alex's comment, it's possible that the problems with the start of your code have blinded me to your real aim.
A
Date
represents an instant in time. That can fall on different dates depending on the time zone, but how do you want that to affect things? Do you want the number of days since the Unix epoch (which is always UTC) or the number of days since the 1st January 1970 in a particular time zone? Why do you want this "number of days" instead of a representation of a date such asLocalDate
? What's the use case here?EDIT: If you just want to know the number of days since the Unix epoch, you can skip most of this:
You shouldn't be going through formatting at all just to get the year / month / day. Just create a
Calendar
, set the relevant time zone, callsetTime
with thedateObj
you've already got, and then clear the hour/minute/second part of the calendar.However, you should explicitly specify which time zone you want to consider - a
Date
represents an instant in time, which will mean different dates in different time zones.You should also consider using Joda Time which makes all of this simpler and has a specific type for dates (
LocalDate
). That would also make it easy to find the number of days between the Unix epoch and a particular date without performing the division yourself.java.time
java.util
Date-Time API 及其格式化 APISimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 现代日期时间 API*。另外,下面引用的是Joda-Time主页的通知< /a>:
使用现代日期时间 API
java.time
的解决方案:您可以将
java.util.Date
的对象转换为即时
使用Date#toInstant
然后您可以使用ChronoUnit# Between
。演示:
输出:
在线演示< /a>
请注意,上面的代码计算以 UTC 表示的两个时刻/瞬间之间的天数。如果您有特定时区的本地日期时间值,则需要指定相应的
ZoneId
。演示:
输出:
在线演示< /a>
从 Trail 了解有关现代日期时间 API 的更多信息:日期时间。
* 无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport 将大部分 java.time 功能向后移植到 Java 6 和 Java 6 7. 如果您正在处理 Android 项目,并且您的 Android API 级别仍然不符合 Java-8,请检查 通过脱糖提供 Java 8+ API 和 如何在Android项目中使用ThreeTenABP。
java.time
The
java.util
Date-Time API and their formatting API,SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.Also, quoted below is a notice from the home page of Joda-Time:
Solution using
java.time
, the modern Date-Time API:You can convert the object of
java.util.Date
toInstant
usingDate#toInstant
and then you can find the number of days from now until this date usingChronoUnit#between
.Demo:
Output:
ONLINE DEMO
Note that the above code calculates the number of days between two moments/instants represented in UTC. If you have date-time values local to a particular timezone, you need to specify the corresponding
ZoneId
.Demo:
Output:
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.