用Java获取当前年份的整数值


300

我需要确定Java中的当前年份为整数。我可以使用java.util.Date(),但已弃用。


3
不,java.util.Date不是过时了,没有像Java 8的一些方法被弃用,但不是整个类。但是您应该避免两者都使用java.util.Datejava.util.Calendar因为它们众所周知是麻烦,混乱和有缺陷的。而是使用java.time(在Java 8中)或Joda-Time
罗勒·布尔克

Answers:


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

不知道这是否符合不设置新日历的标准?(为什么反对这样做?)


1
看到您的答案后,日历将是一个很好的对象。我当时正在寻找单线飞机,但我认为Calendar不会为我提供那种服务。事实证明我是错的!谢谢!
karlgrz

并发又如何,如果其他线程/库代码段更改了当前时间呢?将其修改为以下内容是否合理:Calendar c = Calendar.getInstance(); 同步(c){c.setTimeInMillis(System.currentTimeMillis()); return c.get(Calendar.YEAR);}
jnr 2012年

1
这会在不同版本的Android中返回不同的值。我正在将Android v4.1.2与v4.2.1进行比较。
toobsco42 2013年

2
@ycnix代码没有并发问题,因此无需对其进行更进一步的编译。Calendar.getInstance().get(Calendar.YEAR) 关于时钟在外部更改是原子的,并且在synchronized(c)本地变量的新实例上执行操作在此毫无意义。
2014年

5
import java.util.Calendar
Dominykas Mostauskis,2015年

139

使用Java 8的时间API(假设您很高兴在系统的默认时区中获得年份),可以使用以下Year::now方法

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

7
我建议始终将可选ZoneId参数传递给,now而不是隐式依赖JVM当前的默认区域(在运行时随时可以更改!)。
罗勒·布尔克

看起来像这样的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);

还有新的Date and Time API JSRJoda Time


这会在不同版本的Android中返回不同的值。我正在将Android v4.1.2与v4.2.1进行比较。
toobsco42 2013年

1
@ toobsco42-尝试搜索“ android calendar.year bug”
工具包

嘿@toolkit,我一直在做一些没有运气的研究。我希望有一个更具体的答案。
toobsco42 2013年

我用4.1.2从手机中取出了SIM卡。因此,网络无法在电话上更新日期和时间。因此,手机在2012年卡住了。看起来这不是4.1.2中的错误。
toobsco42 2013年

14

最简单的方法是从日历获取年份。

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

Calendar.YEAR不是当前年份。
工具包

因此定义了Calendar.YEAR。public final static int YEAR = 1;
cagcowboy

2
Calendar上的get()API获取由常量指定的字段处的数据。年份位于“日历”对象的1字段中!Calendar.getInstance()正在获取当前日期。 java.sun.com/j2se/1.4.2/docs/api/java/util/...
鲍勃·金

这会在不同版本的Android中返回不同的值。我正在将Android v4.1.2与v4.2.1进行比较。
toobsco42 2013年

我用4.1.2从手机中取出了SIM卡。因此,网络无法在电话上更新日期和时间。因此,手机在2012年卡住了。看起来这不是4.1.2中的错误。
toobsco42

13

您还可以使用java.time.YearMonth(从Java 8开始)中的2种方法:

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

您错误地复制了很久以前发布的另一个答案。您产生与问题无关的一个月。并且您忽略了时区的关键问题。而且格式混乱。很高兴看到您参与Stack Overflow。但是这个答案还不够好。编辑以纠正其弱点,并增加其他答案已经提供的价值以外的其他价值。或者删除您的答案,然后再收集否决票。PS超级头像图标!
罗勒·布尔克

非常感谢。我已编辑。链接与我的方式有所不同
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年!
Dr. aNdRO

10

tl; dr

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

时区

答案拉菲Khatchadourian明智地展示了如何使用新的java.time包中的Java 8.但是这个答案未能解决时区的关键问题在确定的日期。

int年= LocalDate.now()。getYear();

该代码取决于JVM的当前默认时区。默认区域用于确定今天的日期。例如,请记住,在巴黎的午夜之后,蒙特利尔的日期仍然是“昨天”。

所以,你的结果可能会受到什么样的机器改变它运行时,用户/管理员更改主机操作系统的时区,或任何Java代码在任何时刻改变JVM的当前默认值。最好指定时区。

顺便说一句,一定要使用正确的时区的名称作为由IANA规定。切勿使用既非标准化也不独特的3-4个字母代码。

java.time

Java 8的java.time中的示例。

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

乔达时代

上面有一些想法,但是使用的是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
懒惰的所有区域ID(与我一样):mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset
FBB,

1
@FBB我建议在Wikipedia页面上找到有关时区名称的IANA官方列表当心:这些区域经常变化惊人。如果你真的想了最新信息,下载的新副本tzdata数据文件自己。您可以仔细阅读文件。而且,您可以在Java实现中替换过时的tzdata。Oracle 为其JVM 提供了一个更新程序工具
罗勒·布尔克

4

如果您的应用程序大量使用Date和Calendar对象,那么您确实应该使用Joda Time,因为它java.util.Date是可变的。java.util.Calendar更新其字段时会出现性能问题,并且对于日期时间算法而言比较笨拙。



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

    }

}

该方法已弃用。几年前,JSR 310中定义的java.time类取代了这个可怕的类。请参见assyliasAnswer中的现代解决方案。
罗勒·布尔克

-1

在Java版本8+中,可以(建议)使用java.time库。ISO 8601设置了写日期的标准方法:YYYY-MM-DDjava.time.Instant使用它,因此(用于UTC):

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

PS以防万一(并且是获取的缩写String,不是int),使用起来Calendar看起来更好,并且可以使区域感知。


您忽略了时区的关键问题。在其他Answer中查看更简单的解决方案。
罗勒·布尔克

-2

您可以使用Integer数学完成整个操作,而无需实例化日历:

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

新年可能会休假一两个小时,但我不觉得这是一个问题吗?



哇,这很沉重,我建议您像cagcowboy所展示的那样保持简单。
LStrike

在所有情况下,这可能都不是最好的选择,但不值得一票。
JohnnyLambada

-4

我在图书馆中使用特殊功能来处理天/月/年整数-

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 ) { 
 ...
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.