我有一个小程序显示从今天开始的当前周,如下所示:
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等)?如果有人能帮助我,我会很感激!
我需要将输入保存为字符串吗?整数?
使用a时JTextField
,您从用户那里获得的输入是a String
,因为日期可以包含像.
或等字符-
,具体取决于您选择的日期格式.您当然也可以使用一些更复杂的输入方法,其中输入字段已经验证了日期格式,并返回日,月和年的单独值,但使用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
为a SimpleDateFormat
来获取模式字符串:
if (defaultFormat instanceof SimpleDateFormat) { SimpleDateFormat sdf = (SimpleDateFormat)defaultFormat; System.out.println("Use date format like: " + sdf.toPattern()); }
@adenoyelle上面的评论提醒我:为您的日期解析代码编写单元测试.
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()
.
YearWeek.from( // Represents week of standard ISO 8601 defined week-based-year (as opposed to a calendar year). LocalDate.parse( "2017-01-23" ) // Represents a date-only value, without time-of-day and without time zone. ) // Returns a `YearWeek` object. .getWeek() // Or, `.getYear()`. Both methods an integer number.
ISO 8601标准周4
如果您希望使用标准的ISO 8601周,而不是本地化的一周定义,请使用ThreeTen-Extra项目中YearWeek
发现的类,该项目为Java 8及更高版本中内置的java.time类添加了功能。
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
用于解析。搜索堆栈溢出以获取使用该类的许多示例。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu" , Locale.US ) ; LocalDate ld = LocalDate.parse( "1/23/2017" , f ) ;
得到YearWeek
。
YearWeek yw = YearWeek.from( ld ) ;
要创建字符串,请考虑将标准ISO 8601格式用于年周 yyyy-Www,例如2017-W45
。或者,您可以提取每个数字。
YearWeek::getWeek
–获取基于星期的年份字段。
YearWeek::getYear
–获取基于周的年份字段。
周的其他定义
上面的讨论假设您遵循周和周编号的ISO 8601定义。相反,如果您想要周和周编号的替代定义,请参见Mobolaji D.使用区域设置的定义的答案。
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
Java SE 8, Java SE 9, Java SE 10, Java SE 11和更高版本-标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。
Java SE 6和 Java SE 7
大多数java.time功能都在ThreeTen- Backport中反向移植到Java 6和7 。
安卓系统
更高版本的Android捆绑了java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP…。
该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。