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/MontrealAfrica/CasablancaPacific/Auckland 。 切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

 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.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

从哪里获取java.time类?

  • Java SE 8Java SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • ThreeTenABP项目特别适用于Android的ThreeTen-Backport (如上所述)。
    • 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。

WeekFields

我创建的这个方法适用于Java 8及更高版本,使用WeekFieldsDateTimeFormatterLocalDateTemporalField

不要忘记根据您的使用情况正确设置日期格式!

 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; } }); }