Java:从任何日期获取周数?
我有一个小程序,显示从今天开始的当前周,如下所示:
GregorianCalendar gc = new GregorianCalendar(); int day = 0; gc.add(Calendar.DATE, day);
然后是显示周数的JLabel:
JLabel week = new JLabel("Week " + gc.get(Calendar.WEEK_OF_YEAR));
所以现在我想要一个JTextField,您可以在其中输入日期,JLabel将使用该日期的周数进行更新。 我真的不知道该怎么做,因为我对Java很新。 我需要将输入保存为字符串吗? 整数? 它必须是什么格式(yyyyMMdd等)? 如果有人能帮助我,我会很感激!
我需要将输入保存为字符串吗? 整数?
使用JTextField
,从用户获得的输入是String
,因为日期可以包含像.
或-
,取决于您选择的日期格式。 您当然也可以使用一些更复杂的输入方法,其中输入字段已经validation了日期格式,并返回日,月和年的单独值,但使用JTextField
当然更容易入手。
它必须是什么格式(yyyyMMdd等)?
这取决于您的要求。 您可以使用SimpleDateFormat类来解析任何日期格式:
String input = "20130507"; String format = "yyyyMMdd"; SimpleDateFormat df = new SimpleDateFormat(format); Date date = df.parse(input); Calendar cal = Calendar.getInstance(); cal.setTime(date); int week = cal.get(Calendar.WEEK_OF_YEAR);
但您更有可能希望使用特定于您的语言环境的日期格式:
import java.text.DateFormat; DateFormat defaultFormat = DateFormat.getDateInstance(); Date date = defaultFormat.parse(input);
要向用户提供要使用的格式的提示,需要将DateFormat
转换为SimpleDateFormat
以获取模式字符串:
if (defaultFormat instanceof SimpleDateFormat) { SimpleDateFormat sdf = (SimpleDateFormat)defaultFormat; System.out.println("Use date format like: " + sdf.toPattern()); }
@adenoyelle上面的评论提醒我: 为您的日期解析代码编写unit testing 。
Java 1.8在java.time
包中为您提供了一些新类:
import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.IsoFields; ZonedDateTime now = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()); System.out.printf("Week %d%n", now.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
大多数遗留日历可以通过互操作性方法轻松转换为java.time.ZonedDateTime
/ java.time.Instant
,在您的特定情况下为GregorianCalendar.toZonedDateTime()
。
您可以将日期存储为String,用户可以使用您指定的几乎任何格式输入日期。 您只需要使用DateFormat
对象来解释它们输入的日期。 例如,请参阅Java中将String转换为Calendar对象的最佳答案 。
Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy"); cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));
要从JTextField
读取日期,您可以使用以下内容替换它:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // or any other date format cal.setTime(sdf.parse(dateTextField.getText()));
然后你只需要按照你在问题中显示的方式读取cal
中的周数。 (这是一个简化的示例。您需要处理DateFormat
parse
方法抛出的潜在ParseException
。)
TL;博士
YearWeek.of( LocalDate.parse( "2017-01-23" ) ) .getWeek() // and .getYear()
ISO 8601标准周
如果您想要标准的ISO 8601周 ,而不是一周的本地化定义,请使用ThreeTen-Extra项目中的YearWeek类, 该类为Java 8及更高版本中内置的java.time类添加function。
ISO-8601将星期定义为始终从星期一开始。 第一周是包含日历年第一个星期四的一周。 因此,本课程中使用的以周为基础的年份与日历年不一致。
首先,获取今天的日期。 LocalDate
类表示没有时间且没有时区的仅日期值。
时区对于确定日期至关重要。 对于任何给定的时刻,日期在全球范围内因地区而异。 例如, 法国巴黎午夜过后几分钟,在魁北克蒙特利尔的 “昨天”仍然是新的一天。
以continent/region
的格式指定适当的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用3-4字母缩写,例如EST
或IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z );
或者让用户通过键入字符串来指定日期。 在许多其他问题和答案中涵盖了解析日期的字符串输入。 最简单的方法是让用户使用标准的ISO 8601格式,YYYY-MM-DD,如2017-01-23
。
LocalDate ld = LocalDate.parse( "2017-01-23" ) ;
对于其他格式,请指定DateTimeFormatter
进行解析。 搜索Stack Overflow有许多使用该类的示例。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu" , Locale.US ) ; LocalDate ld = LocalDate.parse( "1/23/2017" , f ) ;
获得YearWeek
。
YearWeek yw = YearWeek.of( ld ) ;
要创建字符串,请考虑使用标准ISO 8601格式的年份 ,yyyy-Www,如2017-W45
。 或者您可以提取每个数字。
-
YearWeek::getWeek
– 获取基于星期的星期字段。 -
YearWeek::getYear
– 获取基于周的年份字段。
一周的其他定义
上面的讨论假设您遵循ISO 8601定义的周和周编号。 如果您想要一个周和周编号的替代定义,请参阅Mobolaji D.使用区域设置定义的答案 。
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。
从哪里获取java.time类?
- Java SE 8 , Java SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和Java SE 7
- 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
- Android的
- ThreeTenABP项目特别适用于Android的ThreeTen-Backport (如上所述)。
- 请参见如何使用ThreeTenABP ….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
WeekFields
我创建的这个方法适用于Java 8及更高版本,使用WeekFields
, DateTimeFormatter
, LocalDate
和TemporalField
。
不要忘记根据您的使用情况正确设置日期格式!
public int getWeekNum(String input) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/dd/yy"); // Define formatting pattern to match your input string. LocalDate date = LocalDate.parse(input, formatter); // Parse string into a `LocalDate` object. WeekFields wf = WeekFields.of(Locale.getDefault()) ; // Use week fields appropriate to your locale. People in different places define a week and week-number differently, such as starting on a Monday or a Sunday, and so on. TemporalField weekNum = wf.weekOfWeekBasedYear(); // Represent the idea of this locale's definition of week number as a `TemporalField`. int week = Integer.parseInt(String.format("%02d",date.get(weekNum))); // Using that locale's definition of week number, determine the week-number for this particular `LocalDate` value. return week; }
您可以使用它,但必须使用java API
SimpleDateFormatter
将日期值解析为正确的日期格式。 您可以指定所需的任何格式。 在那之后你可以操作来获得一年中的一周。
public static int getWeek() { return Calendar.getInstance().get(Calendar.WEEK_OF_YEAR); }
工作正常并返回当前实时的周
这个对我有用
public void sortListItems(List list) { Collections.sort(list, new Comparator () { DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); @Override public int compare(PostModel o1, PostModel o2) { int ret = 0; try { ret = dateFormat.parse(o1.getDate()).compareTo(dateFormat.parse(o2.getDate())); return ret; } catch (ParseException e) { e.printStackTrace(); } return ret; } }); }