tl;博士
LocalDate.now().with( // Get today’s date, then move to another date.
TemporalAdjusters.previousOrSame( // An implementation of `TemporalAdjuster` interface, used for algorithms to move to another date.
DayOfWeek.valueOf( “Monday”.toUpperCase() ) // Get the enum Object with te corresponding hard-coded name in English such as `DayOfWeek.MONDAY`.
)
)
DayOfWeek
DayOfWeek 枚举包含七个对象,一周中的每一天都有一个。
英语
这七个对象的名称都是英文的,全部大写。所以你可以从英文单词中得到对象。
String input = “Monday”.toUpperCase() ;
DayOfWeek dow = DayOfWeek.valueOf( input ) ;
其他语言
对于英语以外的其他语言,定义一个 List 填充每周的每一天的名称。使用从DayOfWeek::getDisplayName 生成的名称,这是一种自动本地化的方法。根据 ISO 8601 标准,从星期一开始列表。搜索该列表以查找与您的输入匹配的内容。获取匹配的序号 1-7(而不是索引号 0-6)。将该数字传递给DayOfWeek.valueOf 以获取DayOfWeek 对象。在某些语言中,您需要搜索一对这样的列表,因为在没有日期上下文的情况下,可能会调用替代拼写来“独立”使用星期几。
这是此类的一个示例。当心:我只是没有经过深思熟虑,也没有进行任何认真的测试,就开始了这门课。使用风险自负。用法:DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" )→DayOfWeek.MONDAY
package com.basilbourque.example;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.DayOfWeek;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
// For a given name of day-of-week in some language, determine the matching `java.time.DayOfWeek` enum object.
// This class is the opposite of `DayOfWeek.getDisplayName` which generates a localized string for a given `DayOfWeek` object.
// Usage… DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" ) → DayOfWeek.MONDAY
// Assumes `FormatStyle.FULL`, for day-of-week names without abbreviation.
// USE AT YOUR OWN RISK. Rough draft, quickly written. No serious testing.
public class DayOfWeekDelocalizer
{
@NotNull
private Locale locale;
@NotNull
private List < String > dayOfWeekNames, dayOfWeekNamesStandalone; // Some languages use an alternate spelling for a “standalone” day-of-week used without the context of a date.
// Constructor. Private, for static factory method.
private DayOfWeekDelocalizer ( @NotNull Locale locale )
{
this.locale = locale;
// Populate the pair of arrays, each having the translated day-of-week names.
int daysInWeek = 7; // Seven days in the week.
this.dayOfWeekNames = new ArrayList <>( daysInWeek );
this.dayOfWeekNamesStandalone = new ArrayList <>( daysInWeek );
for ( int i = 1 ; i <= daysInWeek ; i++ )
{
this.dayOfWeekNames.add( DayOfWeek.of( i ).getDisplayName( TextStyle.FULL , this.locale ) );
this.dayOfWeekNamesStandalone.add( DayOfWeek.of( i ).getDisplayName( TextStyle.FULL_STANDALONE , this.locale ) );
}
// System.out.println( this.dayOfWeekNames );
// System.out.println( this.dayOfWeekNamesStandalone );
}
// Constructor. Private, for static factory method.
// Personally, I think it unwise to default implicitly to a `Locale`. But I included this in case you disagree with me, and to follow the lead of the *java.time* classes. --Basil Bourque
private DayOfWeekDelocalizer ( )
{
this( Locale.getDefault() );
}
// static factory method, instead of constructors.
// See article by Dr. Joshua Bloch. http://www.informit.com/articles/article.aspx?p=1216151
// The `Locale` argument determines the human language and cultural norms used in de-localizing input strings.
synchronized static public DayOfWeekDelocalizer of ( @NotNull Locale localeArg )
{
DayOfWeekDelocalizer x = new DayOfWeekDelocalizer( localeArg ); // This class could be optimized by caching this object.
return x;
}
// Attempt to translate the name of a day-of-week to look-up a matching `DayOfWeek` enum object.
// Returns NULL if the passed String value is not found to be a valid name of day-of-week for the human language and cultural norms of the `Locale` specified when constructing this parent object, `DayOfWeekDelocalizer`.
@Nullable
public DayOfWeek parse ( @NotNull String input )
{
int index = this.dayOfWeekNames.indexOf( input );
if ( - 1 == index )
{ // If no hit in the contextual names, try the standalone names.
index = this.dayOfWeekNamesStandalone.indexOf( input );
}
int ordinal = ( index + 1 );
DayOfWeek dow = ( ordinal > 0 ) ? DayOfWeek.of( ordinal ) : null; // If we have a hit, determine the DayOfWeek. Else return null.
return dow;
}
// `Object` overrides.
@Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
DayOfWeekDelocalizer that = ( DayOfWeekDelocalizer ) o;
return locale.equals( that.locale );
}
@Override
public int hashCode ( )
{
return locale.hashCode();
}
public static void main ( String[] args )
{
// Quick testing.
// DayOfWeekDelocalizer x = DayOfWeekDelocalizer.of( Locale.JAPAN );
if ( DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" ).equals( DayOfWeek.MONDAY ) )
{
System.out.println( "GOOD - Canada French 'lundi' is parsing to DayOfWeek.MONDAY." );
} else
{
System.out.println( "BAD - Canada French 'lundi' is NOT parsing to DayOfWeek.MONDAY." );
}
}
}
提示:使用字符串表示DayOfWeek 很笨拙。您的代码应该传递一个 DayOfWeek 枚举对象。
LocalDate
接下来我们需要当前日期。
LocalDate today = LocalDate.now() ;
比隐式依赖 JVM 当前的默认时区更好地明确说明您想要/预期的时区。
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
LocalDate today = LocalDate.now( z ) ;
TemporalAdjuster
通过应用TemporalAdjuster 移动到另一个日期。 TemporalAdjusters 类提供了我们需要的实现。
TemporalAdjuster ta = TemporalAdjusters.previousOrSame( dow ) ;
LocalDate ld = today.with( ta ) ;
注意 java.time 使用不可变对象。因此,方法不是修改对象,而是生成一个新的不同对象,该对象具有基于原始值的更改值。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。