Nhận giá trị nguyên của năm hiện tại trong Java


300

Tôi cần xác định năm hiện tại trong Java là một số nguyên. Tôi chỉ có thể sử dụng java.util.Date(), nhưng nó không được dùng nữa.


3
Không, java.util.Datekhông phản đối, không phải là của Java 8. Một số phương thức của nó đang bị phản đối nhưng không phải là toàn bộ lớp. Nhưng bạn nên tránh cả hai java.util.Datejava.util.Calendarvì chúng nổi tiếng là rắc rối, khó hiểu và thiếu sót. Thay vào đó, hãy sử dụng java.time (trong Java 8) hoặc Joda-Time .
Basil Bourque

Câu trả lời:


636
int year = Calendar.getInstance().get(Calendar.YEAR);

Không chắc chắn nếu điều này đáp ứng với tiêu chí không thiết lập Lịch mới? (Tại sao phe đối lập làm như vậy?)


1
Khi thấy câu trả lời của bạn, Lịch sẽ là một đối tượng tốt để sử dụng. Tôi đang tìm kiếm một lớp lót và tôi không nghĩ Lịch sẽ có cái đó cho tôi. Tôi đã chứng minh là sai! Cảm ơn!
karlgrz

Điều gì về tương tranh, điều gì xảy ra nếu luồng / đoạn mã thư viện khác thay đổi thời gian hiện tại? Sẽ không hợp lý nếu sửa đổi nó thành một cái gì đó như: Lịch c = Lịch.getInstance (); đã đồng bộ hóa (c) {c.setTimeInMillis (System.c currentTimeMillis ()); return c.get (Lịch.YĂM NĂM);}
jnr

1
Điều này trả về một giá trị khác nhau trong các phiên bản khác nhau của Android. Tôi đang so sánh Android v4.1.2 với v4.2.1.
toobsco42

2
@ycnix Không có vấn đề tương tranh với mã, vì vậy không cần phải biên dịch thêm. Calendar.getInstance().get(Calendar.YEAR) là nguyên tử liên quan đến đồng hồ được thay đổi bên ngoài, và thực hiện synchronized(c)một trường hợp mới của một biến cục bộ dù sao cũng sẽ rất vô nghĩa ở đây.
số

5
import java.util.Calendar
Dominykas Mostauskis

139

Thời gian sử dụng Java API 8 của (giả sử bạn đang hạnh phúc để có được những năm theo múi giờ mặc định của hệ thống của bạn), bạn có thể sử dụng các Year::nowphương pháp :

int year = Year.now().getValue();

7
Tôi đề nghị luôn luôn chuyển ZoneIdđối số tùy chọn nowthay vì dựa hoàn toàn vào vùng mặc định hiện tại của JVM (có thể thay đổi bất kỳ lúc nào trong thời gian chạy!).
Basil Bourque

Có vẻ như BTW này: int year = Year.now(ZoneId.of("America/New_York")).getValue(); docs.oracle.com/javase/8/docs/api/java/time/Year.html#now--
bcmoney

25

Đơn giản nhất (sử dụng Lịch, xin lỗi) là:

 int year = Calendar.getInstance().get(Calendar.YEAR);

Ngoài ra còn có API JSR Ngày và Giờ mới , cũng như Joda Time


Điều này trả về một giá trị khác nhau trong các phiên bản khác nhau của Android. Tôi đang so sánh Android v4.1.2 với v4.2.1.
toobsco42

1
@ toobsco42 - hãy thử googling cho 'android calendar.year bug'
bộ công cụ

Xin chào @toolkit, tôi đã thực hiện một số nghiên cứu không có may mắn. Tôi đã hy vọng cho một câu trả lời cụ thể hơn.
toobsco42

Tôi đã tháo thẻ SIM ra khỏi điện thoại với 4.1.2. Vì vậy, mạng không thể cập nhật Ngày và Giờ trên điện thoại. Do đó, điện thoại đã bị kẹt trong năm 2012. Có vẻ như đây không phải là một lỗi trong 4.1.2.
toobsco42

14

Cách dễ nhất là lấy năm từ Lịch.

// year is stored as a static member
int year = Calendar.getInstance().get(Calendar.YEAR);

Lịch.YĂM không phải là năm hiện tại.
bộ công cụ

Lịch.YEAR được định nghĩa do đó ... chung kết tĩnh int YEAR = 1;
cagcowboy

2
API get () trên Lịch lấy mốc thời gian tại trường được chỉ định bởi hằng số. Năm nằm trong trường 1 trong đối tượng Lịch! Calendar.getInstance () đang nhận được ngày hiện tại. java.sun.com/j2se/1.4.2/docs/api/java/util/ Kẻ
Bob King

Điều này trả về một giá trị khác nhau trong các phiên bản khác nhau của Android. Tôi đang so sánh Android v4.1.2 với v4.2.1.
toobsco42

Tôi đã tháo thẻ SIM ra khỏi điện thoại với 4.1.2. Vì vậy, mạng không thể cập nhật Ngày và Giờ trên điện thoại. Do đó, điện thoại đã bị kẹt trong năm 2012. Có vẻ như đây không phải là một lỗi trong 4.1.2.
toobsco42

13

Bạn cũng có thể sử dụng 2 phương thức từ java.time.YearMonth(Kể từ Java 8):

import java.time.YearMonth;
...
int year = YearMonth.now().getYear();
int month = YearMonth.now().getMonthValue();

Bạn sao chép không chính xác một câu trả lời khác được đăng từ lâu. Và bạn sản xuất một tháng không liên quan đến Câu hỏi. Và bạn bỏ qua vấn đề quan trọng của múi giờ. Và định dạng của bạn là lộn xộn. Tôi rất vui khi thấy bạn tham gia Stack Overflow. Nhưng câu trả lời này không đủ tốt. Chỉnh sửa để sửa các điểm yếu của nó và thêm nhiều giá trị hơn các Câu trả lời khác đã được cung cấp. Hoặc xóa Câu trả lời của bạn trước khi thu thập phiếu bầu. Biểu tượng avatar siêu PS!
Basil Bourque

Cám ơn nhiều, ông bạn. Tôi đã chỉnh sửa. theo cách của tôi thì hơi khác một chút
Zhurov Konstantin

10

Nếu bạn muốn năm của bất kỳ đối tượng ngày nào, tôi đã sử dụng phương pháp sau:

public static int getYearFromDate(Date date) {
    int result = -1;
    if (date != null) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        result = cal.get(Calendar.YEAR);
    }
    return result;
}

kết quả là năm 1970!
Tiến sĩ aNdRO

10

tl; dr

ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  )
             .getYear()

Múi giờ

Câu trả lời của Raffi Khatchadourian cho thấy một cách khôn ngoan cách sử dụng gói java.time mới trong Java 8. Nhưng câu trả lời đó không giải quyết được vấn đề quan trọng của múi giờ trong việc xác định ngày.

int năm = LocalDate.now (). getYear ();

Mã đó phụ thuộc vào múi giờ mặc định hiện tại của JVM. Vùng mặc định được sử dụng để xác định ngày hôm nay là ngày nào. Ví dụ, hãy nhớ rằng trong khoảnh khắc sau nửa đêm ở Paris, ngày ở Montréal vẫn là "ngày hôm qua".

Vì vậy, kết quả của bạn có thể thay đổi tùy theo máy chạy trên máy, người dùng / quản trị viên thay đổi múi giờ của hệ điều hành máy chủ hoặc bất kỳ mã Java nào tại bất kỳ thời điểm nào thay đổi mặc định hiện tại của JVM. Tốt hơn để xác định múi giờ.

Nhân tiện, luôn luôn sử dụng tên múi giờ thích hợp theo định nghĩa của IANA . Không bao giờ sử dụng mã 3-4 chữ cái không được tiêu chuẩn hóa hoặc duy nhất.

java.time

Ví dụ trong java.time của Java 8.

int year = ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  ).getYear() ;

Joda-Thời gian

Một số ý tưởng như trên, nhưng sử dụng thư viện Joda-Time 2.7.

int year = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).getYear() ;

Năm tăng / giảm

Nếu mục tiêu của bạn là nhảy một năm tại một thời điểm, không cần phải trích xuất số năm. Cả Joda-Time và java.time đều có các phương pháp để cộng / trừ một năm tại một thời điểm. Và những phương pháp đó rất thông minh, xử lý Giờ tiết kiệm ánh sáng ban ngày và các bất thường khác.

Ví dụ trong Joda-Time 2.7.

DateTime oneYearAgo = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).minusYears( 1 ) ;

2
Tất cả ID khu vực cho những người lười biếng (như tôi): mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset
FBB

1
@FBB Tôi đề xuất trang Wikipedia cho danh sách IANA chính thức của tên múi giờ. Cẩn thận: Những khu vực thay đổi đáng ngạc nhiên thường xuyên. Nếu bạn thực sự muốn up-to-date thông tin, tải về một bản sao mới của các tzdatatập tin dữ liệu cho mình. Bạn có thể kiểm tra lại tập tin. Và bạn có thể thay thế một tzdata lỗi thời trong triển khai Java của bạn. Oracle cung cấp một công cụ cập nhật cho JVM của họ.
Basil Bourque

4

Nếu ứng dụng của bạn đang sử dụng nhiều đối tượng Ngày và Lịch, bạn thực sự nên sử dụng Joda Time, vì java.util.Datecó thể thay đổi. java.util.Calendarcó vấn đề về hiệu năng khi các trường của nó được cập nhật và rất khó hiểu đối với số học datetime.



3

Như một số người đã trả lời ở trên:

Nếu bạn muốn sử dụng biến sau, sử dụng tốt hơn:

int year;

year = Calendar.getInstance().get(Calendar.YEAR);

Nếu bạn cần một năm cho một điều kiện bạn nên sử dụng tốt hơn:

Calendar.getInstance().get(Calendar.YEAR)

Ví dụ: sử dụng nó trong một lần thực hiện trong khi séc được giới thiệu không nhỏ hơn năm hiện tại - 200 hoặc nhiều hơn năm hiện tại (Có thể là năm sinh):

import java.util.Calendar;
import java.util.Scanner;

public static void main (String[] args){

    Scanner scannernumber = new Scanner(System.in);
    int year;

    /*Checks that the year is not higher than the current year, and not less than the current year - 200 years.*/

    do{
        System.out.print("Year (Between "+((Calendar.getInstance().get(Calendar.YEAR))-200)+" and "+Calendar.getInstance().get(Calendar.YEAR)+") : ");
        year = scannernumber.nextInt();
    }while(year < ((Calendar.getInstance().get(Calendar.YEAR))-200) || year > Calendar.getInstance().get(Calendar.YEAR));
}

3

Sử dụng mã sau cho java 8:

LocalDate localDate = LocalDate.now();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int date = localDate.getDayOfMonth();

0

Trong trường hợp của tôi không có cái nào ở trên được làm việc. Vì vậy, sau khi thử rất nhiều giải pháp tôi đã tìm thấy bên dưới một giải pháp và nó hiệu quả với tôi

import java.util.Scanner;
import java.util.Date;

public class Practice
{   
    public static void main(String[] args)
    {
        Date d=new Date();  
        int year=d.getYear();
        int currentYear=year+1900;    

        System.out.println(currentYear);

    }

}

Phương pháp đó không được chấp nhận. Và lớp khủng khiếp đó đã được thay thế từ nhiều năm trước bởi các lớp java.time được định nghĩa trong JSR 310. Xem giải pháp hiện đại trong Trả lời bằng assylias .
Basil Bourque

-1

Trong phiên bản Java 8+ có thể (khuyên dùng) thư viện java.time . ISO 8601 thiết lập cách tiêu chuẩn để viết ngày: YYYY-MM-DDjava.time.Instantsử dụng nó, vì vậy (cho UTC):

import java.time.Instant;
int myYear = Integer.parseInt(Instant.now().toString().substring(0,4));

PS chỉ trong trường hợp (và rút ngắn để nhận String, không int), sử dụng có Calendarvẻ tốt hơn và có thể được nhận biết theo vùng.


Bạn đang bỏ qua vấn đề quan trọng của múi giờ. Xem giải pháp đơn giản hơn trong câu trả lời khác .
Basil Bourque

-2

Bạn có thể thực hiện toàn bộ bằng cách sử dụng toán học Integer mà không cần phải khởi tạo lịch:

return (System.currentTimeMillis()/1000/3600/24/365.25 +1970);

Có thể nghỉ một hoặc hai giờ vào năm mới nhưng tôi không có ấn tượng đó là một vấn đề?


9
bạn đang làm việc cho apple, có lẽ? macworld.com/article/2023580/ từ
Stefan Paul Noack

wow, cái này rất nặng, tôi sẽ đề nghị giữ cho nó đơn giản như cagcowboy đã cho thấy nó.
LStrike

Điều này có thể không phải là tốt nhất trong mọi trường hợp, nhưng nó không xứng đáng được downvote.
JohnnyLambada

-4

Tôi sử dụng các hàm đặc biệt trong thư viện của mình để làm việc với số ngày / tháng / năm -

int[] int_dmy( long timestamp ) // remember month is [0..11] !!!
{
  Calendar cal = new GregorianCalendar(); cal.setTimeInMillis( timestamp );
  return new int[] { 
    cal.get( Calendar.DATE ), cal.get( Calendar.MONTH ), cal.get( Calendar.YEAR )
  };
};


int[] int_dmy( Date d ) { 
 ...
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.