Displaying the last two digits of the current year in Java - java

How can I display only the last two digits of the current year without using any substring algorithms or any third party libraries?
I have tried the below method and it gave a four-digit year. I want to know whether there are any date formatting options available to get the current year in two-digit format.
Calendar.getInstance().get(Calendar.YEAR);

You can simply use the modulo operator:
int lastTwoDigits = Calendar.getInstance().get(Calendar.YEAR) % 100;
Edit: Using a SimpleDateFormat, as #R.J proposed, is the better solution if you want the result to be a string. If you need an integer, use modulo.

You can use a SimpleDateFormat to format a date as per your requirements.
DateFormat df = new SimpleDateFormat("yy"); // Just the year, with 2 digits
String formattedDate = df.format(Calendar.getInstance().getTime());
System.out.println(formattedDate);
Edit: Depending on the needs/requirements, either the approach suggested by me or the one suggested by Robin can be used. Ideally, when dealing with a lot of manipulations with the Date, it is better to use a DateFormat approach.

This is a one-liner:
System.out.println(Year.now().format(DateTimeFormatter.ofPattern("uu")));
I am using java.time.Year, one of a number of date and time classes introduced in Java 8 (and also backported to Java 6 and 7). This is just one little example out of very many where the new classes are more convenient and lead to clearer code than the old classes Calendar and SimpleDateFormat.
If you just wanted the two-digit number, not as a string, you may use:Year.now().getValue() % 100.
The other answers were good answers in 2013, but the years have moved on. :-)
Edit: New Year doesn’t happen at the same time in all time zones. To make the dependency on time zone clear in the code I would usually write Year.now(myDesiredTimeZoneId), for example in the form Year.now(ZoneId.systemDefault()).

String.format() also has Date/Time Conversions.
To get the last two digits of the current year,
String.format("%ty", Year.now());
This works with a number of the java.time classes, including Year, YearMonth, LocalDate, LocalDateTime, and ZonedDateTime.

In Kotlin
Call this function and pass time in parameter
Example :
Input Parameter : "2021-08-09T16:01:38.905Z"
Output : 09 Aug 21
private val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
private val outputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
fun calculateDateMonthYear(time: String): String {
val inputTime = inputFormat.parse(time)
val convertDateMonthYear = outputFormat.format(inputTime!!)
val timeInMilliseconds = outputFormat.parse(convertDateMonthYear)!!
val mTime: Calendar = Calendar.getInstance()
mTime.timeInMillis = timeInMilliseconds.time
val date_cal = SimpleDateFormat("dd")
val month_date = SimpleDateFormat("MMM")
val year_cal = SimpleDateFormat("yy")
val date = date_cal.format(mTime.time)
val month_name = month_date.format(mTime.time)
val year = year_cal.format(mTime.time)
return "$date $month_name $year"
}

The solution of #Robin Krahl is a bit hacky but I like it. We could avoid the cases commented by #Albert Tong if we add a leading zero. In order that we have the last two digits of the year, I suppose that the result should be a String. In case we could not use the solution of #jaco0646. We could do this:
String yearStr = addLeadingZero(Calendar.getInstance().get(Calendar.YEAR) % 100)
private String addLeadingZero(int num) {
String result = String.valueOf(num);
if(num < 10){
result = "0" + result;
}
return result;
}

I know the question asked for how to do this in Java but Google sent me here when asking about Groovy, so I'll add my answer for that here.
I came up with this based on the Java answer provided by Rahul:
String lastTwoYearDigits = new Date().format("yy")

Related

How to find the first day of any ChronoUnit including quarters in Java?

What I am trying to achieve is a simple method which would use a ChronoUnit + duration to return the first day of the following ChronoUnit.
Context:
ChronoUnit unit = ChronoUnit.MONTHS(WEEKS, QUARTERS, YEARS, DAYS); // Supplied by an enum instance
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate start = LocalDate.parse("1990-12-15",df);
LocalDate end = LocalDate.parse("1991-06-07",df);
LocalDate lastCompoundDate = end;
LocalDate current = start;
ArrayList compoundingDates = new ArrayList<LocalDate>();
while (current.isBefore(end)) {
compoundingDates.add(current);
current = findFirstDateOf(current.plus(duration, unit), unit);
}
compoundingDates.add(end)
return CompoundingDates
Not sure what my best bet for the implementation is, I googled and it seems like getting a a first day of week and month might be trivial with standard java classes, but quarters are a bit tricker. I found people suggesting this: https://www.threeten.org/threeten-extra/ as well, but don't know if that's a way to go since it doesn't provide a clear interface I am looking for.
In a nutshell, I just want to avoid doing all the if-elif-elif depending on the type of chrono unit and wonder if there is a clean, simple way to express that in java. If it's impossible at least maybe there is a clean way to do it for everything, but quarters?
You can use the firstMonthOfQuarter method of the Month enum to help you adjust a LocalDate to the beginning of the quarter. A solution using this could look something like this.
public static LocalDate startOfQuarter(LocalDate arg) {
Month firstMonthOfQuarter = arg.getMonth().firstMonthOfQuarter();
return arg.withDayOfMonth(1).withMonth(firstMonthOfQuarter.getValue());
}

how to change the current date

my method accepts - hours, minutes, seconds and milliseconds separated by sign / as a string parameter
how can I add to the current date the parameters that come to the method.
Example 1: today, 02/10/2021, the method receives metnode data (10/10/10/10) - output - 02/10/2021 10:10:10
Example 2: today, 02/10/2021, the method receives metnode data (55/10/10/10) - output - 02/12/2021 07:10:10
That is, you need to add 55 hours 10 seconds 10 seconds and 10 milliseconds to the current date.
you cannot use the Calendar and StringTokenizer classes.
public void method(String s) {
s = s.replaceAll("/", "-");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
final LocalDateTime now = LocalDateTime.parse(s, formatter.withResolverStyle(ResolverStyle.LENIENT));
System.out.println(now);
}
i found the withResolverStyle (ResolverStyle.LENIENT) method
but did not understand how to use it.
A lenient DateTimeFormatter is enough
I don’t know if it’s the best solution. That probably depends on taste. It does use the ResolverStyle.LENIENT that you mentioned and generally works along the lines of the code in your question, only fixed and slightly simplified.
My formatter includes both date and time. This is necessary for surplus hours to be converted to days.
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-dd H/m/s/")
.appendValue(ChronoField.MILLI_OF_SECOND)
.toFormatter()
.withResolverStyle(ResolverStyle.LENIENT);
Next thing we need a string that matches the formatter. So let’s prepend the date to the time string that we already have got:
String timeString = "55/10/10/10";
LocalDate today = LocalDate.now(ZoneId.of("America/Regina"));
String dateTimeString = "" + today + ' ' + timeString;
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
The output from my code when I ran it today (February 10) was:
2021-02-12T07:10:10.010
A different idea: use Duration
Edit: An alternative is to use the Duration class. A reason for doing that would be that it really appears that you are adding a duration rather than setting the time of day. A liability is that parsing your string into a Duration is a bit tricky. The Duration.parse method that we want to use only accepts ISO 8601 format. It goes like PT55H10M10.010S for a period of time of 55 hours 10 minutes 10.010 seconds. And yes, milliseconds need to be given as a fraction of the seconds.
String isoTimeString = timeString.replaceFirst("(/)(\\d+)$", "$100$2")
.replaceFirst("(\\d+)/(\\d+)/(\\d+)/0*(\\d{3})", "PT$1H$2M$3.$4S");
Duration dur = Duration.parse(isoTimeString);
LocalDateTime dateTime = LocalDate.now(ZoneId.of("Asia/Kathmandu"))
.atStartOfDay()
.plus(dur);
When I ran it just now — already February 11 in Kathmandu, Nepal — the output was:
2021-02-13T07:10:10.010
I am using two calls to replaceFirst(), each time using a regular expression. The first call simply adds some leading zeroes to the milliseconds. $1 and $2 in the replacement string give us what was matched by the first and the second group denoted with round brackets in the regular expression.
The second replaceFirst() call established the ISO 8601 format, which includes making sure that the milliseconds are exactly three digits so they work as a decimal fraction of the seconds.
Link: ISO 8601
Try this:
public void method(String s) {
String[] arr = s.split("/");
LocalDateTime now = LocalDateTime.of(
LocalDate.now(), LocalTime.of(0, 0))
.plusHours(Integer.parseInt(arr[0]))
.plusMinutes(Integer.parseInt(arr[1]))
.plusSeconds(Integer.parseInt(arr[2]))
.plusNanos(Integer.parseInt(arr[3]) * 1_000_000L);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
System.out.println(now.format(formatter));
}
Look into the LocalDateTime documentation. It offers various means for combining dates. Such as:
plus(amount, unit)
plusDays(days)
plusHours(hours)
plusMinutes(minutes)
just for simplicity , you can your LocalDateTime class. it is easy to understand. please refer to below code is used to add the hours, minuts, second and nanos to current Date Time.
this Date Time then can easy formatted by any format pattern as required.
public void addDateTime(int hours, int minuts, int seconds, int nanos) {
LocalDateTime adt = LocalDateTime.now();
System.out.println(adt);
adt = adt.plusHours(hours);
adt = adt.plusMinutes(minuts);
adt = adt.plusSeconds(seconds);
adt = adt.plusNanos(nanos);
System.out.println(adt);
}

DatePicker setting month wrong

Can anyone tell me why the date is being set to next month instead of this month?
Even though im setting the dateFormatted variable as "28/08/2014" its setting the date to "28/07/2014".
I can simply go -1 at the month but it will mess up the date in January.
Is there some other way i should be setting the date?
Thanks
UtilDateModel model;
JDatePanelImpl datePanel;
DatePickerImpl datePicker;
model = new UtilDateModel();
model.setDate(yearInt, monthInt, dayInt);
model.setSelected(true);
datePanel = new JDatePanelImpl(model);
datePicker = new JDatePickerImpl(datePanel);
// String dateFormatted = (String) result[1];
String dateFormatted = "28/08/2014";
System.out.println("Date Formatted : " + (String) result[1]);
int day = Integer.parseInt(dateFormatted.substring(0, 2)); // Correct
int month = Integer.parseInt(dateFormatted.substring(3, 5)); // Correct
int year = Integer.parseInt(dateFormatted.substring(6, 10)); // Correct
System.out.println(day);
System.out.println(month);
System.out.println(year);
model.setDate(year, month, day);
model.setSelected(true);
You're doing date parsing wrong, please use a SimpleDateFormat or the like
The problem that you are seeing is probably related to the fact that some fields are 0-based and some are 1-based.
UPDATE
Dates should not be stored as strings in the database, instead use the available date types.
Date parsing in general is much trickier than you might think. DST, leap years, language,... all comes into play.
The newest java iteration has a complete rewrite for date handling based on joda time (http://www.joda.org/joda-time/) but you can also use the "old" way of date parsing in java which is not bad, simply different.
You should look at the javadoc of SimpleDateFormat, it will tell you why you need lower case "yyyy" for example and upper case "MM". The formatter will give you a Date which you can probe with Calendar for the required fields.
All the while it will take into account all the niggling details about date handling.
I'm not known with the 'JDatePicker' package, but after doing some research, i've found this, please read article 3 on this page. It says month number is 0 based, so januari should be 0 ( 1st month minus 1).

adding/removing days from date code fix needed

I have this code here:
public static String AddRemoveDays(String date, int days) throws ParseException
{
SimpleDateFormat k = new SimpleDateFormat("yyyyMMdd");
Date d = k.parse(date);
d = new Date(d.getTime() + days*86400000);
String time = k.format(d);
return time;
}
It take String formed "yyyyMMdd", and adds int days to it. It should work then the days is negative - then he would substract the days from the date. When it does it's math, it returns String formated "yyyyMMdd".
At least that is what it should do. It works for small numbers, but if I try to add (or remove), for example, a year (365 or -365), it returns wierd dates.
What's the problem?
Should I do it a completley another way?
d = new Date(d.getTime() + days*86400000);
If you multiply 86400000 by 365 integer cant hold it. Change 86400000 to Long
d = new Date(d.getTime() + days*86400000L);
and it will be fine.
Hard to say what's going on without specific dates.
If you're committed to doing this with the raw Java classes, you might want to look at using Calendar -e.g.
Calendar calendar = Calendar.getInstance();
calendar.setTime(d);
calendar.add(Calendar.DATE, days); // this supports negative values for days;
d = calendar.getTime();
That said, I would recommend steering clear of the java Date classes, and look to use jodaTime or jsr310 instead.
e.g. in jsr310, you could use a DateTimeFormatter and LocalDate:
DateTimeFormatter format = DateTimeFormatters.pattern("yyyyMMdd");
LocalDate orig = format.parse(dateString, LocalDate.rule());
LocalDate inc = orig.plusDays(days); // again, days can be negative;
return format.print(inc);

high performance function for date arithmetic

I need to write the high performance function which calculates the new datetime based on given datetime and timeshift. It accept 2 arguments:
String, representing the date in format YYYYMMDDHHmm
Integer, representing the timeshift in hours
Function returns the string in format of 1st argument which is composed as result of applying the timeshift to 1st argument
It is known in advance that the first argument is always the same during the program lifetime.
My implementation has the following steps:
parsing 1st argument to extract the year,month,date, hours,min
creating GregorianCalendar(year, month, date, hours, min) object
applying method GregorianCalendar.add(HOUR,timeshift)
applying SimpleDateFormat to convert result back into string
Issue is that I do not take advantage from the fact that 1st argument is always the same.
If I will create a class member GregorianCalendar(year, month, date, hours, min), then after the 1st call to my function this object will be modified, which is not good, because I cannot reuse it for the following calls.
If you can, use the Joda-Time library, which makes date arithmetic very simple:
DateTime dt = new DateTime();
DateTime twoHoursLater = dt.plusHours(2);
They have a DateTimeFormatter class that you'd use to do the parsing of your input date-time string into a DateTime, eg:
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMddHHmm");
DateTime dt = fmt.parseDateTime(myDateString);
DateTime result = dt.plusHours(myTimeshiftInHours);
And Joda-Time interoperates well with java.util.Date too. I love it!
If the first argument is a value that will not change often, perhaps use a cache :
static private Map<String,Calendar> dateCache = new HashMap<String,Calendar>();
Then, in your method, check of the first argument (ex: String dateStr) is a key in the cache
Calendar cal;
if (dateCache.containsKey(dateStr)) {
cal = (Calendar)(dateCache.get(dateStr)).clone();
} else {
// parse date
cal = new GregorianCalendar(...);
dateCache.put(dateStr, (Calendar)cal.clone());
}
And add your timeshift value.
How about this,
Parse and hold on to your fixed date, call it fixedDate
Let timeShift be a time shift in hours, then Date shiftedDate = new Date(fixedDate.getTime() + (timeShift * 3600000)) would be your calculated shifted date (see this and this for understanding)
Apply SimpleDateFormat to convert shiftedDate to string.
Repeat steps 2 and 3 indefinitely, fixedDate is not modified and can be reused.
I'd try simple memoisation:
// This is not thread safe. Either give each thread has its own
// (thread confined) converter object, or make the class threadsafe.
public class MyDateConverter {
private String lastDate;
private int lastShift;
private String lastResult;
public String shiftDate(String date, int shift) {
if (shift == lastShift && date.equals(lastDate)) {
return lastResult;
}
// Your existing code here
lastDate = date;
lastShift = shift
lastResult = result;
return result;
}
}
Note this simple approach is most effective if the shift and date values rarely change. If either changes frequently, you'd need a more complicated cache, the code will be more complicated and the overheads (for a cache miss) will be higher.
If you simply want to avoid repeating step 1 (and maybe 2) again and again, parse the date once, then save the Date you get. You can then apply this date to your Calendar (with setDate()) before each add step again (or create a new GregorianCalendar, measure if it matters).

Categories

Resources