รับค่าจำนวนเต็มของปีปัจจุบันใน Java


300

ฉันต้องกำหนดปีปัจจุบันใน Java เป็นจำนวนเต็ม ฉันสามารถใช้java.util.Date()แต่ก็เลิกใช้แล้ว


3
ไม่java.util.Dateเป็นไม่เลิกไม่เป็นชวา 8. บางส่วนของวิธีการจะเลิก แต่ไม่ทั้งชั้น แต่คุณควรหลีกเลี่ยงทั้งคู่java.util.Dateและjava.util.Calendarในขณะที่พวกเขากำลังลำบากสับสนและมีข้อบกพร่อง ใช้java.time (ใน Java 8) หรือJoda-Timeแทน
Basil Bourque

คำตอบ:


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

ไม่แน่ใจว่าตรงตามเกณฑ์ของการไม่ตั้งค่าปฏิทินใหม่หรือไม่? (ทำไมฝ่ายค้านถึงทำเช่นนั้น?)


1
เมื่อเห็นคำตอบของคุณปฏิทินจะเป็นวัตถุที่น่าใช้ ฉันกำลังมองหาสายการบินเดียวและฉันไม่คิดว่า Calendar จะเป็นเช่นนั้นสำหรับฉัน พิสูจน์แล้วว่าผิดฉัน! ขอบคุณ!
karlgrz

เกิดอะไรขึ้นกับการทำงานพร้อมกันจะเกิดอะไรขึ้นถ้าเธรด / ชิ้นส่วนอื่น ๆ ของรหัสห้องสมุดเปลี่ยนเวลาปัจจุบัน? มันจะไม่เหมาะสมที่จะปรับเปลี่ยนเป็นสิ่งที่ชอบ: ปฏิทิน c = Calendar.getInstance (); ทำข้อมูลให้ตรงกัน (c) {c.setTimeInMillis (System.currentTimeMillis ()); return c.get (Calendar.YEAR);}
jnr

1
ส่งคืนค่าที่แตกต่างใน Android รุ่นต่าง ๆ ฉันกำลังเปรียบเทียบ Android v4.1.2 กับ v4.2.1
toobsco42

2
@ycnix ไม่มีปัญหาเกี่ยวกับการทำงานพร้อมกันของรหัสดังนั้นไม่จำเป็นต้องทำให้คอมไพล์มากขึ้น Calendar.getInstance().get(Calendar.YEAR) เป็นอะตอมเกี่ยวกับนาฬิกาที่มีการเปลี่ยนแปลงจากภายนอกและการทำsynchronized(c)กับอินสแตนซ์ใหม่ของตัวแปรท้องถิ่นจะไม่มีจุดหมายใด ๆ ที่นี่
nos

5
import java.util.Calendar
Dominykas Mostauskis

139

โดยใช้เวลาใน Java API 8 (สมมติว่าคุณมีความสุขที่จะได้รับในปีโซนเวลาเริ่มต้นของระบบของคุณ) คุณสามารถใช้วิธีการ :Year::now

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

7
ฉันขอแนะนำให้ส่งZoneIdอาร์กิวเมนต์ที่เป็นตัวเลือกไปยังnowแทนที่จะพึ่งพาปริยายในโซนเริ่มต้นปัจจุบันของ JVM (ซึ่งสามารถเปลี่ยนแปลงได้ตลอดเวลาระหว่างรันไทม์!)
Basil Bourque

ซึ่งมีลักษณะเช่นนี้ BTW: int year = Year.now(ZoneId.of("America/New_York")).getValue(); docs.oracle.com/javase/8/docs/api/java/time/Year.html#now--
bcmoney

25

ง่ายที่สุด (ใช้ปฏิทินขออภัย) คือ:

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

นอกจากนี้ยังมีใหม่วันที่และเวลา API JSRเช่นเดียวกับJoda เวลา


ส่งคืนค่าที่แตกต่างใน Android รุ่นต่าง ๆ ฉันกำลังเปรียบเทียบ Android v4.1.2 กับ v4.2.1
toobsco42

1
@ toobsco42 - ลอง googling สำหรับ 'ข้อผิดพลาด calendar.year หุ่นยนต์'
เครื่องมือ

เฮ้ @ เครื่องมือช่างฉันได้ทำการวิจัยโดยที่ไม่มีโชค ฉันหวังว่าจะได้คำตอบที่เฉพาะเจาะจงมากขึ้น
toobsco42

ฉันลบซิมการ์ดออกจากโทรศัพท์ด้วย 4.1.2 ดังนั้นเครือข่ายจึงไม่สามารถอัปเดตวันที่และเวลาบนโทรศัพท์ ดังนั้นโทรศัพท์ติดในปี 2012 ดูเหมือนว่านี่ไม่ใช่ข้อผิดพลาดใน 4.1.2
toobsco42

14

วิธีที่ง่ายที่สุดคือการรับปีจากปฏิทิน

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

ปฏิทินปีไม่ใช่ปีปัจจุบัน
ชุดเครื่องมือ

ปฎิทิน. ปีถูกกำหนดดังนั้น ... สาธารณะคงที่ int ปีสุดท้าย = 1;
cagcowboy

2
get () API ในปฏิทินรับข้อมูลที่อยู่ในฟิลด์ที่ระบุโดยค่าคงที่ ปีตั้งอยู่ในเขตข้อมูล 1 ในวัตถุปฏิทิน! Calendar.getInstance () กำลังได้รับวันที่ปัจจุบัน java.sun.com/j2se/1.4.2/docs/api/java/util/…
Bob King

ส่งคืนค่าที่แตกต่างใน Android รุ่นต่าง ๆ ฉันกำลังเปรียบเทียบ Android v4.1.2 กับ v4.2.1
toobsco42

ฉันลบซิมการ์ดออกจากโทรศัพท์ด้วย 4.1.2 ดังนั้นเครือข่ายจึงไม่สามารถอัปเดตวันที่และเวลาบนโทรศัพท์ ดังนั้นโทรศัพท์ติดในปี 2012 ดูเหมือนว่านี่ไม่ใช่ข้อผิดพลาดใน 4.1.2
toobsco42

13

คุณสามารถใช้ 2 วิธีจากjava.time.YearMonth(ตั้งแต่ Java 8):

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

คุณซ้ำคำตอบอื่นที่โพสต์เมื่อไม่นานมานี้ และคุณสร้างเดือนซึ่งไม่เกี่ยวข้องกับคำถาม และคุณไม่สนใจปัญหาสำคัญของเขตเวลา และการจัดรูปแบบของคุณยุ่ง ฉันดีใจที่เห็นคุณมีส่วนร่วมใน Stack Overflow แต่คำตอบนี้ไม่ดีพอ แก้ไขเพื่อแก้ไขจุดอ่อนและเพิ่มมูลค่าให้มากกว่าคำตอบอื่นที่มีอยู่แล้ว หรือลบคำตอบของคุณก่อนที่จะรวบรวมคะแนนลง ไอคอนประจำตัว PS Super!
Basil Bourque

ขอบคุณมากครับ ฉันแก้ไขแล้ว ลิงก์แตกต่างกันเล็กน้อยตามทางของฉัน
Zhurov Konstantin

10

หากคุณต้องการปีของวัตถุวันที่ใด ๆ ฉันใช้วิธีต่อไปนี้:

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

ผลที่ได้คือ 1970!
ดร. aNdRO

10

TL; DR

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

เขตเวลา

คำตอบโดยRaffi Khatchadourianแสดงวิธีใช้แพ็คเกจ java.timeใหม่ใน Java 8 อย่างชาญฉลาดแต่คำตอบนั้นล้มเหลวในการแก้ไขปัญหาสำคัญของเขตเวลาในการกำหนดวันที่

int year = LocalDate.now (). getYear ();

รหัสนั้นขึ้นอยู่กับเขตเวลาเริ่มต้นปัจจุบันของ JVM โซนเริ่มต้นใช้ในการกำหนดวันที่วันนี้ ตัวอย่างเช่นจำไว้ว่าในช่วงเวลาหลังเที่ยงคืนในปารีสวันที่ในมอนทรีออลยังคงเป็น 'เมื่อวาน'

ดังนั้นผลลัพธ์ของคุณอาจแตกต่างกันไปโดยสิ่งที่เครื่องจะทำงานบนผู้ใช้ / การเปลี่ยนโซนเวลาโฮสต์ OS หรือรหัส Java ใด ๆ ผู้ดูแลระบบในช่วงเวลาใดการเปลี่ยนแปลงเริ่มต้นปัจจุบัน JVM ของ ดีกว่าที่จะระบุเขตเวลา

อย่างไรก็ตามใช้ชื่อเขตเวลาที่เหมาะสมตามที่กำหนดโดย IANAเสมอ อย่าใช้รหัสตัวอักษร 3-4 ตัวที่ไม่ได้มาตรฐานหรือไม่ซ้ำ

java.time

ตัวอย่างใน java.time ของ Java 8

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

Joda เวลา

แนวคิดบางอย่างข้างต้น แต่ใช้ห้องสมุดJoda-Time 2.7

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

ปีที่เพิ่มขึ้น / ลดลง

หากเป้าหมายของคุณคือการข้ามปีละครั้งไม่จำเป็นต้องแยกหมายเลขปี ทั้ง Joda-Time และ java.time มีวิธีเพิ่ม / ลบปีละครั้ง และวิธีการเหล่านั้นฉลาดควบคุมเวลาตามฤดูกาลและความผิดปกติอื่น ๆ

ตัวอย่างใน Joda-Time 2.7

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

2
รหัสโซนทั้งหมดสำหรับคนขี้เกียจ (เช่นฉัน): mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset
FBB

1
@FBB ฉันขอแนะนำหน้า Wikipedia สำหรับรายการเขตเวลาอย่างเป็นทางการของ IANA ระวัง: โซนเหล่านี้มักจะเปลี่ยนอย่างแปลกใจ ถ้าคุณอยากขึ้น-to-date ข้อมูลดาวน์โหลดสำเนาใหม่ของแฟ้มข้อมูลด้วยตัวคุณเอง คุณสามารถอ่านไฟล์ได้ และคุณสามารถแทนที่ tzdata ที่ล้าสมัยในการนำ Java ไปใช้ของคุณ Oracle จัดเตรียมเครื่องมือตัวอัปเดตสำหรับ JVM ของตน tzdata
Basil Bourque

4

หากแอปพลิเคชันของคุณใช้วัตถุ Date และ Calendar อย่างหนักคุณควรใช้ Joda Time เพราะjava.util.Dateไม่สามารถเปลี่ยนแปลงได้ java.util.Calendarมีปัญหาประสิทธิภาพเมื่อเขตข้อมูลได้รับการปรับปรุงและ clunky สำหรับเลขคณิตของวันที่



3

ตามที่บางคนตอบไว้ด้านบน:

หากคุณต้องการใช้ตัวแปรในภายหลังให้ใช้:

int year;

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

หากคุณต้องการปีสำหรับเงื่อนไขที่คุณควรใช้:

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

ตัวอย่างเช่นใช้ในสิ่งที่ต้องทำในขณะที่การตรวจสอบปีที่แนะนำไม่น้อยกว่าปีปัจจุบัน -200 หรือมากกว่าปีปัจจุบัน (อาจเป็นปีเกิด):

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

ใช้รหัสต่อไปนี้สำหรับ java 8:

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

0

ในกรณีของฉันไม่มีการทำงานใด ๆ ข้างต้น ดังนั้นหลังจากลองใช้วิธีแก้ปัญหามากมายฉันพบว่ามันใช้งานได้

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

    }

}

วิธีการนั้นเลิกใช้แล้ว และที่ระดับสาหัสถูกแทนที่ปีที่ผ่านมาโดยjava.timeเรียนที่กำหนดไว้ใน JSR 310 ดูวิธีการแก้ปัญหาที่ทันสมัยในคำตอบโดย assylias
Basil Bourque

-1

ใน Java เวอร์ชัน 8+ สามารถ (แนะนำให้ใช้) ใช้ไลบรารีjava.time ISO 8601กำหนดวิธีมาตรฐานในการเขียนวันที่: YYYY-MM-DDและjava.time.Instantใช้ดังนั้น (สำหรับUTC):

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

PS ในกรณี (และย่อมาจากการรับStringไม่ใช่int) การใช้งานCalendarดูดีขึ้นและสามารถทำให้โซนรับรู้ได้


คุณไม่สนใจปัญหาสำคัญของเขตเวลา ดูวิธีการแก้ปัญหาที่ง่ายในคำตอบอื่น
Basil Bourque

-2

คุณสามารถทำสิ่งทั้งหมดโดยใช้เลขจำนวนเต็มโดยไม่ต้องสร้างอินสแตนซ์ของปฏิทิน:

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

อาจปิดปีหรือสองชั่วโมงในปีใหม่ แต่ฉันไม่ได้รับความประทับใจที่เป็นปัญหาหรือไม่


9
คุณทำงานกับแอปเปิ้ลหรือเปล่า? macworld.com/article/2023580/…
Stefan Paul Noack

ว้าวนี่มันหนักมากฉันอยากจะแนะนำให้มันง่ายเหมือน cagcowboy ได้แสดงมัน
LStrike

นี่อาจไม่ใช่สิ่งที่ดีที่สุดในทุกสถานการณ์ แต่มันไม่สมควรได้รับ downvotes
JohnnyLambada

-4

ฉันใช้ฟังก์ชั่นพิเศษในห้องสมุดของฉันเพื่อทำงานกับ ints วัน / เดือน / ปี -

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 ) { 
 ...
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.