为 Calendar 对象禁用 DST

Disable DST for Calendar object

我正在解析一个以逗号分隔的文件,其中有两个字段需要转换为时间戳。我得到一个日期,一个单独的字段给我午夜过去的分钟数......例如:

10/15/2020, 360

现在 360,在大多数日子里,将是早上 6 点(360/60 = 6),但在 DST 上说它可能是 5 或 7。问题是我总是期望在早上 6 点输出,即使它是 DST天.

Calendar cal = Calendar.getInstance();
cal.setTime(schedDate);

cal.add(Calendar.MINUTE, Integer.parseInt(minutes));

return new Timestamp(cal.getTimeInMillis());

我试过添加以下内容:

cal.set(cal.DST_OFFSET, 0);

但这似乎并不能解决问题。我不确定日历是否具有禁用 DST 偏移的任何内置功能,但我们将不胜感激任何建议

使用 LocalDateTime,它不必处理 time-zone(因此不必处理夏令时)。请注意 LocalDateTimethe modern date-time API.

的一部分
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDate.parse("10/15/2020", DateTimeFormatter.ofPattern("M/d/u")).atStartOfDay()
                .plusHours(6);
        System.out.println(ldt);
    }
}

输出:

2020-10-15T06:00

我还建议您停止使用 error-prone 和过时的 java.util date-time API.

如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and .

Trail: Date Time.

了解有关现代 date-time API 的更多信息

使用java.time,可以包含系统的时区,也可以给定一个固定的。

以下代码展示了如何做到这一点:

public static void main(String[] args) {
    // example input
    String date = "10/15/2020";
    long minutes = 360;
    // create a LocalDate from the String considering its format
    LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("MM/dd/uuuu"));
    // create a minimum LocalTime (the beginning of a day) and add the minutes you got
    LocalTime timeOfDay = LocalTime.MIN.plusMinutes(minutes);
    // create a zone-aware object by using the date, the time of day and the system's zone
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate,
                                                    timeOfDay, 
                                                    ZoneId.systemDefault());
    // print the toString() method (implicitly)
    System.out.println(zonedDateTime);
    // or use a custom format
    System.out.println(zonedDateTime.format(DateTimeFormatter
                                            .ofPattern("MM/dd/uuuu HH:mm:ss")));
}

它输出以下内容(在具有 UTC+2 的系统上是 运行):

2020-10-15T06:00+02:00[Europe/Berlin]
10/15/2020 06:00:00

现在开始了,我们可以让 java.time 解析 CSV 文件(逗号分隔值文件)中的两个字段并将它们合并:

        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M/d/u");
        DateTimeFormatter minuteOfDayFormatter = new DateTimeFormatterBuilder()
                .appendValue(ChronoField.MINUTE_OF_DAY)
                .toFormatter();
        
        String dateString = "10/15/2020";
        String timeString = "360";
        
        LocalDate date = LocalDate.parse(dateString, dateFormatter);
        LocalTime time = LocalTime.parse(timeString, minuteOfDayFormatter);
        LocalDateTime dateTime = date.atTime(time);
        
        System.out.println(dateTime);

输出为:

2020-10-15T06:00

如果您认为 SQL 数据库需要 java.sql.Timestamp,那么您很可能不需要。您可以将 LocalDateTime 对象传递给您的数据库,例如使用 PreparedStatement.setObject()。如果您需要控制时区(通常是个好主意),请先将其转换为 OffsetDateTimeInstant。搜索方法。