生成&解析“年月”来自Java的文本中的值 [英] Generate & parse "Year-Month" values in text from Java

查看:98
本文介绍了生成&解析“年月”来自Java的文本中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个HTML弹出菜单列出各种年份组合。每个菜单项都有一个本地化的字符串表示,例如 2015年11月,用于内容显示,以及编码值的属性,如 201511



例如:

 < select name =selectPeriod> 
< option value =201511> 2015年11月< / option>
< option value =201510> 2015年10月< / option>
< option value =201509> 2015年9月< / option>

我使用java.util.Calendar生成编码值字符串。

  int month = Calendar.getInstance()。get(Calendar.MONTH)+1; 
int year = Calendar.getInstance()。get(Calendar.YEAR);
String v = String.valueOf(year)+ String.valueOf(month);

这是有效的,但使用日历(日期加上时间)似乎很奇怪)当我真正关心的是没有日期或时间的年+月。



现代Java中有一些更好的方法来处理一年+

解决方案

确实,在现代Java中有一个更优雅的方式来处理YearMonth,java.time框架内置于Java 8以及以后。



您的示例代码还有其他一些问题:




  • 获得当前时刻两次。
    多次获得当前时刻两次是一个不好的做法。如果这两行代码发生在午夜的中风周围,那么您将会在两个不同的日期,甚至两个不同的月份甚至几年的时间里工作!

  • 忽略时区。
    下面讨论



java.time



旧的java.util.Calendar / .Date类是非常麻烦的,应该避免。它们已被Java 8替代,后来被 java.time 框架。



新课程的灵感来源于非常成功的 Joda-Time 框架,作为其继承者,在概念上类似但重新架构。由 JSR 310 定义。由 ThreeTen-Extra 项目扩展。请参阅教程



YearMonth



新类包括一个类, YearMonth ,完全是为了您的目的:表示一个年份+月,没有任何日期,时间或时区。



我建议在您的业务逻辑中使用此类的对象,诉诸于



时区



虽然没有时区包含在年份,请注意,时区对于确定当前的今年至关重要。当前日期,因此YearMonth在任何时候都在世界各地变化。一天的新的一天在诸如巴黎之前的东部早于西方,比如仍然是昨天的蒙特利尔。



如果示例代码中省略了时区,则将隐式使用JVM的当前默认时区。这种隐含使用意味着您的结果可能会因以下几个原因而有所不同:您的代码可能会移动到另一台机器,sysadmin可能会更改主机的默认值,甚至更糟糕的是,在同一个JVM中运行的任何应用程序的任何线程中的任何代码都可以< a href =http://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#setDefault-java.util.TimeZone- =nofollow>更改时区在运行时 。更好地指定所需/预期的时区( ZoneId 在java.time)。

  ZoneId zoneId = ZoneId。 (美洲/蒙特利尔); 
YearMonth yearMonth = YearMonth.now(zoneId);



字符串格式



toString 方法默认情况下在java.time类中使用标准的 ISO 8601 格式。您的格式 YYYYMM 与标准格式相似,但在这种特殊情况下(年月),需要连字符以避免歧义, YYYY-MM 。大多数标准格式允许一个基本的变体省略连字符,但不在这里。



我强烈建议使用ISO 8601格式使您的日期时间值的字符串表示只要有可能。

  String output = yearMonth.toString(); 




2015-12




我强烈建议您在HTML属性中使用该格式。坚持ISO 8601将简化您的生活。像这样(注释连字符):

 < option value =2015-11> 2015年11月< / option> 

但是,如果你坚持,你可以通过指定一个自定义格式化模式

  DateTimeFormatter formatter = DateTimeFormatter.ofPattern(yyyyMM); 
String output = yearMonth.format(formatter);




201512




本地化字符串



让java.time执行本地化显示文本的工作。请注意 区域设置 传递给DateTimeFormatter,而不是隐含地依赖于JVM当前的默认语言环境。

  Locale locale = Locale .CANADA_FRENCH; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(MMM yyyy,locale);
String output = yearMonth.format(formatter);




déc。 2015



I have an HTML popup menu listing various year-month combinations. Each menu item has a localized string representation such as Nov 2015 for content display, along with an attribute of a coded value such as 201511.

For example:

<select name="selectPeriod">
    <option value="201511">Nov 2015</option>
    <option value="201510">Oct 2015</option>
    <option value="201509">Sept 2015</option>

I generate the coded value string using java.util.Calendar.

int month = Calendar.getInstance().get(Calendar.MONTH)+1;
int year = Calendar.getInstance().get(Calendar.YEAR);
String v = String.valueOf( year ) + String.valueOf( month );

This works, but it seems weird to be using Calendar (a date plus a time-of-day) when all I really care about is year + month without a date or time-of-day.

Is there some better way in modern Java to handle a year + month?

解决方案

Indeed there is a more elegant way to handle YearMonth in modern Java, with the java.time framework built into Java 8 and later.

Also your example code suffers from a couple other problems:

  • Getting current moment twice.
    Getting the current moment twice, redundantly, is a bad practice. If those two lines of code happen to occur around the stroke of midnight, you will be working with two different dates and possibly two different months or even years!
  • Ignoring the issue of time zone.
    Discussed below.

java.time

The old java.util.Calendar/.Date classes are notoriously troublesome and should be avoided. They have been supplanted in Java 8 and later by the java.time framework.

The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

YearMonth

The new classes include a class, YearMonth, exactly for your purpose: To represent a year+month without any date, time-of-day, or time zone.

I recommend using objects of this class in your business logic, resorting to strings only where necessary such as generating that HTML.

Time Zone

While no time zone is included inside a YearMonth, note that a time zone is crucial in determining the current YearMonth. The current date, and therefore YearMonth, varies around the world at any moment. A new day dawns in the east such as Paris earlier than in the west such as Montréal where it is still "yesterday".

If the time zone is omitted as in your example code, the JVM’s current default time zone is implicitly used. This implicit use means your results may vary for any of several reasons: Your code may move to another machine, a sysadmin may change the host machine’s default, or even worse, any code in any thread of any app running within the same JVM can change the time zone at runtime. Better to specify the desired/expected time zone (ZoneId in java.time).

ZoneId zoneId = ZoneId.of( "America/Montreal" );
YearMonth yearMonth = YearMonth.now( zoneId );

String Formats

The toString method by default in java.time classes use the standard ISO 8601 formats. Your format, YYYYMM is similar to the standard formats but in this particular case (year-month) a hyphen is required to avoid ambiguity, YYYY-MM. Most of the standard formats allow a "basic" variation omitting the hyphens, but not here.

I strongly suggest making your String representations of date-time values in ISO 8601 format whenever possible.

String output = yearMonth.toString ();

2015-12

I strongly suggest using that format in your HTML attribute. Sticking with ISO 8601 will simplify your life. Like this (note the hyphen):

<option value="2015-11">Nov 2015</option>

But if you insist, you could build the string without the hyphen by specifying a custom formatter pattern.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyyMM" );
String output = yearMonth.format ( formatter );

201512

Localized Strings

Let java.time do the work of localizing the display text. Notice the Locale passed to the DateTimeFormatter rather than relying implicitly on the JVM’s current default Locale.

Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "MMM yyyy" , locale );
String output = yearMonth.format ( formatter );

déc. 2015

这篇关于生成&amp;解析“年月”来自Java的文本中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆