禁用日历对象的夏时制

huangapple go评论65阅读模式
英文:

Disable DST for Calendar object

问题

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

10/15/2020360

现在对于大多数日子360分钟相当于上午6点360/60 = 6),但在夏令时中它可能是5点或7点问题是即使是夏令时的那一天我始终需要输出上午6点

```java
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);

但似乎没有解决问题。我不确定Calendar是否有任何内置功能来禁用夏令时偏移,但如果有任何建议,将不胜感激。


<details>
<summary>英文:</summary>

I&#39;m parsing a comma delimited file that has two field I need to convert to a timestamp. I get a date, and a separate field gives me minutes passed midnight... for instance:

10/15/2020, 360

now 360, for most days, would be 6am (360/60 = 6) but on DST says it could be either 5 or 7. The problem is I&#39;m always expected to output 6am even when it&#39;s a DST day.

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

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

return new Timestamp(cal.getTimeInMillis());


I&#39;ve tried adding the following:

cal.set(cal.DST_OFFSET, 0);


but that doesn&#39;t seem to fix the issue. I&#39;m not sure if calendar has any built in functionality to disable DST offsets, but any suggestions would be appreciated



</details>


# 答案1
**得分**: 3

使用`LocalDateTime`,它不需要处理时区(因此也不需要考虑夏令时)。注意,`LocalDateTime`是[现代日期时间API][1]的一部分。

```java
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

我还建议您停止使用容易出错且过时的java.util日期时间API。

如果您在进行Android项目,并且您的Android API级别仍不符合Java-8,请查看通过desugaring使用Java 8+ API以及如何在Android项目中使用ThreeTenABP

在**教程: 日期时间**中了解更多关于现代日期时间API的信息。

英文:

Use LocalDateTime which does not have to deal with time-zone (and hence DST). Note that LocalDateTime is part of the 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(&quot;10/15/2020&quot;, DateTimeFormatter.ofPattern(&quot;M/d/u&quot;)).atStartOfDay()
				.plusHours(6);
		System.out.println(ldt);
	}
}

Output:

2020-10-15T06:00

I also suggest you stop using the error-prone and outdated java.util date-time API.

If you are doing it for your 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.

Learn more about the modern date-time API at Trail: Date Time.

答案2

得分: 2

使用 java.time,您可以使用系统的时区或指定一个固定的时区。

以下代码展示了如何实现这一点:

public static void main(String[] args) {
    // 示例输入
    String date = "10/15/2020";
    long minutes = 360;
    // 从字符串创建一个LocalDate,考虑其格式
    LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("MM/dd/uuuu"));
    // 创建一个最小的LocalTime(一天的开始),并添加您得到的分钟数
    LocalTime timeOfDay = LocalTime.MIN.plusMinutes(minutes);
    // 使用日期、时间和系统时区创建一个区域感知对象
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate,
                                                    timeOfDay, 
                                                    ZoneId.systemDefault());
    // 打印toString()方法(隐式)
    System.out.println(zonedDateTime);
    // 或者使用自定义格式
    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
英文:

Using java.time, you can involve the time zone of the system or give it a fixed one.

The following code shows how you could do that:

public static void main(String[] args) {
	// example input
	String date = &quot;10/15/2020&quot;;
	long minutes = 360;
	// create a LocalDate from the String considering its format
	LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern(&quot;MM/dd/uuuu&quot;));
	// 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&#39;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(&quot;MM/dd/uuuu HH:mm:ss&quot;)));
}

It outputs the following (which was run on a system with UTC+2):

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

答案3

得分: 2

现在我们可以让 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

如果你认为你需要一个 java.sql.Timestamp 来操作你的 SQL 数据库,大概情况并非如此。你可以将 LocalDateTime 对象传递给数据库,例如使用 PreparedStatement.setObject() 方法。如果你需要控制时区(通常是个好主意),先将其转换为 OffsetDateTimeInstant。搜索相关方法。

英文:

Now we’re at it, we can let java.time parse both fields from the CSV file (comma separated values file) and combine them:

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

Output is:

> 2020-10-15T06:00

If you thought you needed a java.sql.Timestamp for your SQL database, you most probably don’t. You may pass the LocalDateTime object to your database using for example PreparedStatement.setObject(). If you need to control the time zone (usually a good idea), convert it to OffsetDateTime or Instant first. Search for how.

huangapple
  • 本文由 发表于 2020年10月9日 22:26:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/64281996.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定