java中的DateTime的使用_C#与Java中的DateTime操作

我是Java的新手。 我有时间从网页上获取,这是"hh:mm"格式(不是24小时)。 这对我来说是一个字符串。 然后我想将这个字符串与今天的日期结合起来,以便创建一个我可以使用的Java Date。

在C#中:

string s ="5:45 PM";

DateTime d;

DateTime.TryParse(s, out d);

在Java中我尝试过:

String s ="5:45 PM";

Date d = new Date(); // Which instantiates with the current date/time.

String[] arr = s.split("");

boolean isPm = arr[1].compareToIgnoreCase("PM") == 0;

arr = arr[0].split(":");

int hours = Integer.parseInt(arr[0]);

d.setHours(isPm ? hours + 12 : hours);

d.setMinutes(Integer.parseInt(arr[1]));

d.setSeconds(0);

有没有更好的方法来实现我想要的?

使用SimpleDateFormat类来处理java中的每种格式。

@AMallal:理想情况下,不要 - 使用java.time代替。

@Jon双向:我的不好

Is there a better way to achieve what I want?

绝对 - 实际上在.NET和Java中都是如此。在.NET中,我(以偏向的方式)建议使用Noda Time,这样您就可以将一天中的某个时间表示为LocalTime,从而精确地解析您期望的模式。

在Java 8中,您可以使用java.time.LocalTime执行相同的操作:

import java.time.*;

import java.time.format.*;

public class Test {

public static void main(String[] args) {

String text ="5:45 PM";

DateTimeFormatter format = DateTimeFormatter.ofPattern("h:mm a");

LocalTime time = LocalTime.parse(text, format);

System.out.println(time);

}

}

一旦你解析了你已经进入适当类型的文本,就可以将它与其他类型结合起来。例如,要使用今天的日期和指定的时间在系统时区中获取ZonedDateTime,您可以使用:

ZonedDateTime zoned = ZonedDateTime.now().with(time);

默认情况下使用系统时区和时钟,使其难以测试 - 我建议传入Clock以获得可测试性。

(Noda Time也提供同样的东西,但略有不同。如果您需要详细信息,请告诉我。)

我强烈建议不要使用java.util.Date,它只是代表一个时刻,并且有一个糟糕的API。

这里的关键点是:

使用明确指定的格式解析文本

将文本解析为表示其传达的信息的类型:一天中的某个时间

将该值与另一个值相结合,该值也应该仔细指定(就时钟和时区而言)

所有这些都将导致清晰,可靠,可测试的代码。 (并且现有的.NET代码不符合任何这些要点,IMO。)

等等,Jon,这并没有给我平等的.NET代码。 我想拥有今天的日期,并将时间推荐给我想要的字符串值。 所以对于今天"16/08/2017 15:45"作为日期对象更好,所以我可以对它进行操作。 当转储到控制台时,这只会给出"17:45"。

@MoonKnight:Date对象是即时的。 你想要什么时区? Date几乎总是使用错误的类型。 我会稍微编辑一下我的答案。

@MoonKnight:扩大了很多。

尼斯。 我只想要一个快照,但我同意你对Date的所有观点。 非常感谢您抽出宝贵的时间来确保详细介绍,我们非常感谢。 我把你所说的一切都带到了船上。 再次感谢。

要解析时间,你可以按@Jon Skeet的答案解释:

String input ="5:45 PM";

DateTimeFormatter parser = DateTimeFormatter.ofPattern("h:mm a", Locale.ENGLISH);

LocalTime time = LocalTime.parse(input, parser);

请注意,我还使用了java.util.Locale,因为如果您不指定它,它将使用系统的默认语言环境 - 并且某些语言环境可以对AM / PM字段使用不同的符号。使用显式语言环境可避免出现这种情况(即使在运行时也可以更改默认语言环境,因此最好使用显式语言环境)。

要结合今天的日期,您需要java.time.LocalDate(获取日期)并与LocalTime组合,以获得LocalDateTime:

// combine with today's date

LocalDateTime combined = LocalDate.now().atTime(time);

然后你可以使用另一个格式化器格式化LocalDateTime:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");

System.out.println(combined.format(fmt));

输出是:

16/08/2017 17:45

如果要将LocalDateTime转换为java.util.Date,则必须注意一些细节。

A java.util.Date表示自1970-01-01T00:00Z(又名Unix Epoch)以来的毫秒数。这是一个瞬间(一个特定的时间点)。有关详细信息,请查看此文章。

因此,相同的Date对象可以表示不同的日期或时间,具体取决于您所处的位置:现在想想,此时此世界上的每个人都处于同一时刻(自1970-01-01T00:00Z以来的相同毫秒数) ),但世界各地的当地日期和时间不同。

LocalDateTime表示"本地"的概念:它是日期(日,月和年)和时间(小时,分钟,秒和纳秒),但与特定时区无关。

相同的LocalDateTime对象可以表示不同时区的不同时刻。因此,要将其转换为Date,您必须定义您想要的时区。

一种选择是使用系统的默认时区:

// convert to system's default timezone

ZonedDateTime atDefaultTimezone = combined.atZone(ZoneId.systemDefault());

// convert to java.util.Date

Date date = Date.from(atDefaultTimezone.toInstant());

但是默认值可能因系统/环境而异,也可以在运行时更改。要不依赖于它并对其进行更多控制,您可以使用显式区域:

// convert to a specific timezone

ZonedDateTime zdt = combined.atZone(ZoneId.of("Europe/London"));

// convert to java.util.Date

Date date = Date.from(zdt.toInstant());

请注意,我使用Europe/London。 API使用IANA时区名称(始终采用Region/City格式,如America/Sao_Paulo或Europe/Berlin)。

避免使用3个字母的缩写(如CST或PST),因为它们不明确且不标准。

您可以通过调用ZoneId.getAvailableZoneIds()获取可用时区列表(并选择最适合您系统的时区)。

此外还有夏令时的极端情况(当LocalDateTime可以存在两次或由于重叠和间隙而不能存在时)。在这种情况下,使用ZonedDateTime的Jon的解决方案避免了这个问题)。

非常好的回答,非常感谢您的时间。 我从中学到了很多东西。 祝一切顺利。

@MoonKnight欢迎您,很乐意提供帮助! 我可以推荐本教程,它是java.time API的一个很好的起点。 干杯!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值