我可以使用以下代码将日期转换为天数。
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的窗口。
但是,当系统中的时间为20.00时,EST或太平洋时区中的相同代码会将最多1天添加到最终结果中。
可能是什么问题?
我们是否需要在代码中明确设置时区?
输入日期不包含任何时间戳..
存储在java.util.Date
而不是java.sql.Date
中是否正确?
答案 0 :(得分:3)
编辑:根据Alex的评论,代码启动时的问题可能会让我对你的真正目标视而不见。
Date
表示即时。根据时区的不同,这可能会落在不同的日期,但您希望这会如何影响事物?您想要自Unix时代(始终为UTC)以来的天数或特定时区内自1970年1月1日以来的天数吗?为什么你想要这个“天数”而不是LocalDate
之类的日期?这里的用例是什么?
编辑:如果您只是想知道自Unix时代以来的天数,您可以跳过大部分内容:
days = dateObj.getTime() / (24 * 60 * 60 * 1000);
你不应该只是为了获得年/月/日而进行格式化。只需创建Calendar
,设置相关时区,使用您已经拥有的setTime
拨打dateObj
,然后清除日历的小时/分钟/秒部分。
但是,您应该明确指定要考虑的时区 - Date
代表即时及时,这意味着不同时区的不同日期。
您还应该考虑使用Joda Time,这使得所有这些变得更简单并且具有特定类型的日期(LocalDate
)。这样也可以很容易地找到Unix纪元和特定日期之间的天数,而无需自己进行划分。
答案 1 :(得分: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)的解决方案:
您可以使用 Instant
将 java.util.Date
的对象转换为 Date#toInstant
,然后您可以使用 ChronoUnit#between
找到从现在到该日期的天数。
演示:
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.GregorianCalendar;
public class Main {
public static void main(String[] args) {
// A sample java.util.Date
Date dateObj = GregorianCalendar.from(ZonedDateTime.of(2021, 10, 2, 22, 25, 0, 0, ZoneOffset.UTC)).getTime();
Instant instant = dateObj.toInstant();
// Difference between now and the given java.util.Date
System.out.println(ChronoUnit.DAYS.between(Instant.now(), instant));
}
}
输出:
99
请注意,上面的代码计算以 UTC 表示的两个时刻/瞬间之间的天数。如果您有特定时区的本地日期时间值,则需要指定相应的 ZoneId
。
演示:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.GregorianCalendar;
public class Main {
public static void main(String[] args) {
ZoneId tz = ZoneId.of("Australia/Brisbane");
// A sample java.util.Date representing the local date and time values in Australia/Brisbane
Date dateObj = GregorianCalendar.from(ZonedDateTime.of(2021, 10, 2, 22, 25, 0, 0, tz)).getTime();
// Difference between now in Australia/Brisbane and the given java.util.Date
System.out.println(ChronoUnit.DAYS.between(Instant.now().atZone(tz), dateObj.toInstant().atZone(tz)));
}
}
输出:
98
从 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。