Java中的日期到日期转换

时间:2011-10-31 11:25:21

标签: java date days

我可以使用以下代码将日期转换为天数。

 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中是否正确?

2 个答案:

答案 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.time

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)的解决方案:

您可以使用 Instantjava.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

ONLINE DEMO

请注意,上面的代码计算以 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

ONLINE DEMO

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 desugaringHow to use ThreeTenABP in Android Project