-1

I am getting the current time in epoch. How can I add 1 month in future?

Date date = new Date();
int epoch = date.getTime();

Datatype for epoch - integer($int64)

To be precise: I want to add 30 days from current time.

I am using a tool that allows Groovy and Java code to be embedded. I used Date class because I can easily import java.text.DateFormat; and import java.text.SimpleDateFormat;. The tool that I have doesn't support Instant.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
user3384231
  • 3,641
  • 2
  • 18
  • 27
  • Do you want a `long`? And how precise do you want it? Give some examples. – Elliott Frisch Oct 31 '20 at 23:56
  • 2
    There's no such thing, believe it or not, as a "1 month" as a duration. The reason for that is that months can be different lengths depending on the month and and year. So what do you want to add? 30 days? The same day and time as today but next month? You have to define precisely how far you want to jump forward from the current time. – CryptoFool Nov 01 '20 at 00:00
  • updated the question. It should be int (int64). I want to add 30 days (current time + 30 ) – user3384231 Nov 01 '20 at 00:04
  • 1
    Nit: epoch's just an ordinary English word, it doesn't need capitalization. – user14387228 Nov 01 '20 at 00:12
  • 1
    30 days and a month is (usually) not the same. Which of them do you want? An `int` is Java is always 32 bits. A 64 bits integer is called a `long`. Which of them do you want? – Ole V.V. Nov 01 '20 at 07:02
  • 1
    I recommend you don’t use `Date`. That class is poorly designed and long outdated. Instead use `ZonedDateTime` and `Instant`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Nov 01 '20 at 07:03
  • What did your search bring up? I’m sure your could have found hundreds if not thousands of relevant posts. – Ole V.V. Nov 01 '20 at 07:25
  • 1
    Which tool have you got that doesn’t support classes that have been with standard Java for 6 years 7 months? Can you upgrade it to an approximately current version? – Ole V.V. Nov 01 '20 at 07:39

4 Answers4

7

Since Java 8, use java.time for time usage

As epoch seconds, adding 30 days:

Instant.now().plus(30, ChronoUnit.DAYS).getEpochSecond()

As epoch milliseconds, adding 30 days:

Instant.now().plus(30, ChronoUnit.DAYS).toEpochMilli()
DigitShifter
  • 801
  • 5
  • 12
  • 1
    Thanks, the tool that I have doesn't support your answer but I have upvoted it. – user3384231 Nov 01 '20 at 00:49
  • 1
    Thanks a lot. Here is a variant with Date otherwise: long epochSecondsPlus30Days = (new Date()).getTime() / 1000L + (30 * 24 * 3600); – DigitShifter Nov 01 '20 at 01:05
  • How’s your answer different than mine that was posted 15 min before yours? – Abhijit Sarkar Nov 01 '20 at 01:11
  • I did not see how it was 15 min ago, but when I saw it first time it was written as Instant.now().plus(30, TimeUnit.DAYS). Otherwise when I look at it now only the conversion to seconds or millis. – DigitShifter Nov 01 '20 at 01:23
  • Other variant of Date and epoch millis: long epochMillisPlus30Days = (new Date()).getTime() + (30 * 24 * 3600 * 1000L) – DigitShifter Nov 01 '20 at 01:28
  • You're right, I did type `TimeUnit.DAYS` initially when the OP asked for imports. That was a mistake, caused by the fact no one, including me, memorizes the import statements. That's one thing IDEs do very well, and humans have better things to do. – Abhijit Sarkar Nov 01 '20 at 01:46
  • I agree in using java.time, the modern Java date and time API. Adding days to an `Instant` assumes that a day is always 24 hours, which it isn’t, so your code gives inaccurate results around summer time transitions and other time anomalies. – Ole V.V. Nov 01 '20 at 07:19
  • getEpochSecond(), is always expressed in UTC time zone, which is great since using normalized time as UTC will make it easy to compare records and logs without involving a counties summer time and so on. Compare: ZonedDateTime.now(ZoneOffset.ofHours(5)).plus(30, ChronoUnit.DAYS).toEpochSecond(); and Instant.now().plus(30, ChronoUnit.DAYS).getEpochSecond(); - they will give the same result, showing that methods will express them in UTC time which is great for a time stamps used in records. – DigitShifter Nov 01 '20 at 10:12
1

You don’t want to use Date, use date time API.

Instant.now().plus(30, ChronoUnit.DAYS)
Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • which java library do I need to import? I am using a tool that allows groovy and java code to be embedded. I used Date function because I can easily import java.text.DateFormat; import java.text.SimpleDateFormat; – user3384231 Nov 01 '20 at 00:13
  • There’s no library you need to import, it’s all part of the JDK 8 onwards. Just use your IDE to do the imports, I don’t have to list them for you. – Abhijit Sarkar Nov 01 '20 at 00:14
  • I agree in using java.time, the modern Java date and time API. Adding days to an `Instant` assumes that a day is always 24 hours, which it isn’t, so your code gives inaccurate results around summer time transitions and other time anomalies. – Ole V.V. Nov 01 '20 at 07:19
  • @OleV.V. On the contrary, the whole point of the date time API is not having to worry about which day falls 13 milliseconds short of 24 hours. In other words, we don't care, unless there is a reason to. – Abhijit Sarkar May 12 '22 at 17:52
  • Well, only the OP can tell what they intended exactly when they said first “1 month” and then “30 days”. Thanks for clarifying what you intended on your part. – Ole V.V. May 13 '22 at 13:14
-1

Here's how I'd do it:

Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 30);
long epoch = calendar.getTimeInMillis();
System.out.println(epoch);

Result:

1606785580218

This is milliseconds. You can divide by 1000 to get the version in seconds. NOTE: The seconds version will fit in an int whereas the milliseconds version requires a long. So it's OK to do this if you want the seconds version in an int:

long epoch = ...
int epochSeconds = (int)(epoch / 1000);

BTW, Unix time (Epoch time, POSIX time) is defined as the number of seconds since 1 January 1970 UTC. Some systems will return the value in milliseconds to provide more accuracy, but such a value is officially a fractional Epoch time multiplied by 1000.

CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • Can i use the datatype for epoch as int? – user3384231 Nov 01 '20 at 00:30
  • YES! See my constantly evolving answer! – CryptoFool Nov 01 '20 at 00:37
  • Also note that I got the 30 day thing started, and now both answers that are upvoted are adding 30 days. Since you do know that you want "a month from today", you can add a month and it makes sense. It will, I believe, always jump to the same date and time in the next month. – CryptoFool Nov 01 '20 at 00:39
  • I recommend you don’t use `Calendar`. That class is poorly designed and long outdated. Instead use `ZonedDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Nov 01 '20 at 07:15
  • 1
    In your comment under a different answer you said the crucial: *my code chooses a representation of the current time in some known timezone (we don't care what it is), …*. You need to care, or you cannot know whether you get the correct result. – Ole V.V. Nov 01 '20 at 09:15
  • 1
    Also I would prefer to be able to read more clearly from your code which known time zone you had chosen. – Ole V.V. Nov 01 '20 at 09:27
  • @OleV.V. - You say "You need to care, or you cannot know whether you get the correct result.". No, I don't. Take my code, comment out the line that adds 30 days, and run it. Then go to `https://www.epochconverter.com/clock`, and you'll see roughly the same value. No timezones visually involved. To get to my second number, don't comment that line back in but instead add 100*60*60*24*30 to the number. You'll get the same result as if you ran my code. Again, no timezone involved. The Calendar has some timezone assigned and knows how to convert from it to Epoch. That all that matters. – CryptoFool Nov 01 '20 at 15:22
  • In a comment under another answer you have stated correctly that the operation uses (depends on?) a known time zone. Now you are telling me incorrectly that time zone doesn’t matter. – Ole V.V. Nov 01 '20 at 15:49
  • While there may not be a time zone with a planned time zone change within the next 30 days, imagine that I had run your code last midnight in America/Toronto time zone. Output with that line commented out: 1604203200000. Result of adding 1000L * 60 * 60 * 24 * 30: 1606795200000. Output from your entire code: 1606798800000. According to your own comment your code produces the wrong result. – Ole V.V. Nov 01 '20 at 16:01
  • @OleV.V. - There may be moments in time when "add 30 days" is ambiguous within an hour. You can't seriously now want to reduce all of these discussions down to that fact, can you? Running my code vs adding 30 days worth of seconds gave me the same result yesterday, and it's giving me the same result today. Let the OP bring up the fact that they care about that one hour in carefully chosen situations, and we can all discuss it more. – CryptoFool Nov 01 '20 at 16:20
  • At least now the OP and all readers should be aware that the question exists and must then decide for themselves. I have nothing more to add. – Ole V.V. Nov 01 '20 at 16:33
  • 1
    That's perfectly fair. – CryptoFool Nov 01 '20 at 16:34
-2

So far all answers are wrong.

That's because what you want is impossible.

You're mixing entirely incompatible concepts. You're asking to add 1 entity that is devoid of timezone and political meaning ('epoch-millis', which explicitly means: No timezone info!) with a concept that cannot be nailed down as meaning anything particular unless you supply timezone and era.

You cannot add a month to an epoch milli. Not because java doesn't let you, or because it is hard to program. You can't do it for the same reason you cannot point at the corner in a circle. It's literally impossible, by definition.

'epoch millis' are a concept that is fundamentally about a moment in time. Things like 'when the sun flared up'. "When I clapped my hands together just now". This concept is best represented in java by an instance of java.time.Instant. It is also represented by a java.util.Date, which is funny, because this is nothing like a Date, and indeed, j.u.Date is an utterly stupid name, and the authors have belatedly realized this, which is why (almost) all of the methods it has are marked @Deprecated with a note describing that Date's very name is a total lie. j.u.Date does not represent dates.

A month, that's an entirely different can of worms. There's nothing solid about a month. It could be 28 days. 30 days. 31 days. 30 days and an extra second tossed in. It could be a month that doesn't even exist, or is only 11 days (when political areas switch timezones, you can get some really bizarre things happening).

So, how do you add 'a month' to any instant in time?

You can't. It's not possible. You'd have no idea what to add, because there is no way to figure out if it's 28 days, 29, 30, 31, let alone leap seconds and era weirdness (recently, samoa switched to the other side of the dateline, and as a consequence, their december was only 30 days. The famous 'october revolution' that introduced communism to russia happened in november, at least as far as the entire world (except the russians) were concerned, because only the russians were on the julian calendar where it was still october. As part of the whole 'communism will take over the world!' scheme one of the very first things they did was get on the gregorian same as the rest of the world, and as a consequence, this date does not exist, AT ALL, in russian history: 1 through 13 feb 1918. They just. . were skipped. One day you wake up in moscow, walk outside, ask somebody: Hey, what date is it (though probably in russian), and they say: Why, 31st of January, comrade. Next day you repeat that exercise and now it is February 19th. So, february 1918 in russia was 15 days long.

See why 'please add 1 month' is just not a thing that could possibly be done unless you tell me when and where? If you tell me 'in russia', then I still don't know if I add 15, or 31, or 30, or 29, or 28. If you tell me 'Februari, in 1918', well, in the rest of the world, februari was 28 days. Only in russia it was 15.

Now, adding 'a month' to some human-oriented date/time construct, such as 'well, right now, in amsterdam', ah, that works: "THIS month, the month it is right now, in amsterdam", that is a question that has an answer. But, 'epoch millis' is java-ese for: "An instant in time, devoid of any and all geographical information", and by missing geo info it is also impossible to know when that is relative to any timezone, and therefore, utterly impossible.

So, what CAN you do? Well, many things, but first you need to figure out what you want to do, and only then can somebody tell you how to do it:

  • I just want to add what feels like an average month, and end up with epoch-millis. Okay, then just add 2.629.800.000, which is a rough estimate (that's about 30.4375 days, which is roughly the average length of a month. I have no idea what possible purpose this would serve, but it's surely a better plan than adding 30 days, or 31 days, or 28 days.
  • I want to first translate this epoch-millis into a time as humans would say it (in turns of year, month, day, hour, minute, and second), and then just increment the month value by 1, and leave it at that, in e.g. a ZonedDateTime object. Okay, then first figure out which timezone you want, then turn your epoch-millis into a ZonedDateTime, and THEN we've arrived at a point where 'add a month to this please' even makes sense, so now we can do that: .plusMonths(1), voila.
  • Same as previous, but then convert that back to epoch millis. Okay, well, do the same thing, and call .toInstant() at the end, and toEpochMillis() on that.

Most other ideas boil down to: Your question makes no sense and cannot be answered.

NB: The above all use the java.time packages. All other options (java.util.Date and java.util.Calendar are broken and unwieldy; generally attempting to do this or any other date-related job in those APIs will either be impossible, will give wrong answers, or there is a way but it is hard to figure out how and the resulting code will be hard to maintain and hard to follow. Why would you voluntarily punch yourself in the face? Why would you voluntary use crap APIs? Don't do that.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72