tl; dr
Month.of( yourMonthNumber ) // Represent a month by its number, 1-12 for January-December.
.getDisplayName( // Generate text of the name of the month automatically localized.
TextStyle.SHORT_STANDALONE , // Specify how long or abbreviated the name of month should be.
new Locale( "es" , "MX" ) // Locale determines (a) the human language used in translation, and (b) the cultural norms used in deciding issues of abbreviation, capitalization, punctuation, and so on.
) // Returns a String.
java.time.Month
Giờ đây, việc thực hiện dễ dàng hơn nhiều trong các lớp java.time thay thế các lớp ngày-giờ kế thừa cũ rắc rối này.
Các Month
enum định nghĩa một chục đối tượng, một cho mỗi tháng.
Các tháng được đánh số từ 1-12 cho tháng 1-12.
Month month = Month.of( 2 ); // 2 → February.
Yêu cầu đối tượng tạo Chuỗi tên của tháng, được bản địa hóa tự động .
Điều chỉnh TextStyle
để chỉ định độ dài hoặc viết tắt bạn muốn tên. Lưu ý rằng trong một số ngôn ngữ (không phải tiếng Anh), tên tháng sẽ thay đổi nếu được sử dụng một mình hoặc như một phần của ngày hoàn chỉnh. Vì vậy, mỗi kiểu văn bản có một …_STANDALONE
biến thể.
Chỉ định a Locale
để xác định:
- Ngôn ngữ của con người nên được sử dụng trong dịch thuật.
- Các chuẩn mực văn hóa nào sẽ quyết định các vấn đề như viết tắt, dấu câu và viết hoa.
Thí dụ:
Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l ); // Or Locale.US, Locale.CANADA_FRENCH.
Tên → Month
đối tượng
FYI, đi theo hướng khác (phân tích cú pháp chuỗi tên tháng để lấy một Month
đối tượng enum) không được tích hợp sẵn. Bạn có thể viết lớp của riêng bạn để làm như vậy. Đây là nỗ lực nhanh chóng của tôi trong một lớp học như vậy. Sử dụng có rủi ro của riêng bạn . Tôi đã đưa ra mã này không có suy nghĩ nghiêm túc cũng như bất kỳ thử nghiệm nghiêm túc nào.
Sử dụng.
Month m = MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) ; // Month.JANUARY
Mã.
package com.basilbourque.example;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Month;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
// For a given name of month in some language, determine the matching `java.time.Month` enum object.
// This class is the opposite of `Month.getDisplayName` which generates a localized string for a given `Month` object.
// Usage… MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) → Month.JANUARY
// Assumes `FormatStyle.FULL`, for names without abbreviation.
// About `java.time.Month` enum: https://docs.oracle.com/javase/9/docs/api/java/time/Month.html
// USE AT YOUR OWN RISK. Provided without guarantee or warranty. No serious testing or code review was performed.
public class MonthDelocalizer
{
@NotNull
private Locale locale;
@NotNull
private List < String > monthNames, monthNamesStandalone; // Some languages use an alternate spelling for a “standalone” month name used without the context of a date.
// Constructor. Private, for static factory method.
private MonthDelocalizer ( @NotNull Locale locale )
{
this.locale = locale;
// Populate the pair of arrays, each having the translated month names.
int countMonthsInYear = 12; // Twelve months in the year.
this.monthNames = new ArrayList <>( countMonthsInYear );
this.monthNamesStandalone = new ArrayList <>( countMonthsInYear );
for ( int i = 1 ; i <= countMonthsInYear ; i++ )
{
this.monthNames.add( Month.of( i ).getDisplayName( TextStyle.FULL , this.locale ) );
this.monthNamesStandalone.add( Month.of( i ).getDisplayName( TextStyle.FULL_STANDALONE , this.locale ) );
}
// System.out.println( this.monthNames );
// System.out.println( this.monthNamesStandalone );
}
// 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 MonthDelocalizer ( )
{
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 MonthDelocalizer of ( @NotNull Locale localeArg )
{
MonthDelocalizer x = new MonthDelocalizer( localeArg ); // This class could be optimized by caching this object.
return x;
}
// Attempt to translate the name of a month to look-up a matching `Month` enum object.
// Returns NULL if the passed String value is not found to be a valid name of month for the human language and cultural norms of the `Locale` specified when constructing this parent object, `MonthDelocalizer`.
@Nullable
public Month parse ( @NotNull String input )
{
int index = this.monthNames.indexOf( input );
if ( - 1 == index )
{ // If no hit in the contextual names, try the standalone names.
index = this.monthNamesStandalone.indexOf( input );
}
int ordinal = ( index + 1 );
Month m = ( ordinal > 0 ) ? Month.of( ordinal ) : null; // If we have a hit, determine the `Month` enum object. Else return null.
if ( null == m )
{
throw new java.lang.IllegalArgumentException( "The passed month name: ‘" + input + "’ is not valid for locale: " + this.locale.toString() );
}
return m;
}
// `Object` class overrides.
@Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
MonthDelocalizer that = ( MonthDelocalizer ) o;
return locale.equals( that.locale );
}
@Override
public int hashCode ( )
{
return locale.hashCode();
}
public static void main ( String[] args )
{
// Usage example:
MonthDelocalizer monthDelocJapan = MonthDelocalizer.of( Locale.JAPAN );
try
{
Month m = monthDelocJapan.parse( "pink elephant" ); // Invalid input.
} catch ( IllegalArgumentException e )
{
// … handle error
System.out.println( "ERROR: " + e.getLocalizedMessage() );
}
// Ignore exception. (not recommended)
if ( MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ).equals( Month.JANUARY ) )
{
System.out.println( "GOOD - In locale "+Locale.CANADA_FRENCH+", the input ‘janvier’ parses to Month.JANUARY." );
}
}
}
Giới thiệu về java.time
Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date
, Calendar
, & SimpleDateFormat
.
Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.
Để tìm hiểu thêm, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow để có nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .
Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của mình. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*
lớp.
Lấy các lớp java.time ở đâu?
- Java SE 8 , Java SE 9 và mới hơn
- Được xây dựng trong.
- Một phần của API Java tiêu chuẩn với triển khai theo gói.
- Java 9 bổ sung một số tính năng nhỏ và các bản sửa lỗi.
- Java SE 6 và Java SE 7
- Phần lớn chức năng của java.time được chuyển ngược sang Java 6 & 7 trong ThreeTen-Backport .
- Android
- Các phiên bản triển khai gói Android mới hơn của các lớp java.time.
- Đối với Android trước đó (<26), các ThreeTenABP dự án thích nghi ThreeTen-backport (nêu trên). Xem Cách sử dụng ThreeTenABP… .
Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là cơ sở chứng minh cho những bổ sung có thể có trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval
, YearWeek
, YearQuarter
, và nhiều hơn nữa .