I have a file I want to encrypt and decrypt based on a date. When writing it, I want to use the current date, but not the time. What would I use for this?
Then, whenever I want to decrypt it, I can just use File.lastModified to get the long date. From here, how do I convert this into only the date (and not the time) it was written (or last modified, which should be the same)?
I would prefer to avoid extra libraries, and if it's overly complex, that's fine because I am encrypting data and complex code would help throw off snoopers. Most of all, it needs to be able to read the date across all locales and platforms in the same manner, so as to not throw off the encryption.
EDIT: URL problem solved. Java wanted a / in between .net and ? in the following:
"http://login.minecraft.net/?user=" + username + "&password=" + password + "&version=99"
Now my encryption class is flipping out over something...
Simple suggestion: first convert the date to a yyyy-mm-dd string. Second hash the string along with any other relevant data you need to make your key. See Convert timestamp long to normal date format for long/date to string conversion.
GregorianCalendar c = new GregorianCalendar(time);
c.set(GregorianCalendar.HOUR, 0);
c.set(GregorianCalendar.HOUR_OF_DAY, 0);
c.set(GregorianCalendar.MINUTE, 0);
c.set(GregorianCalendar.SECOND, 0);
c.set(GregorianCalendar.MILLISECOND, 0);
c.getTimeInMillis();
The long time value is defined as:
A milliseconds value represents the number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.
So to round down to the nearest day you need something like:
public static final long OneDay = 1000l * 60l * 60l * 24l;
long today = (System.currentTimeMillis() / OneDay) * OneDay;
Date lastMidnight = new Date(today);
But please do not forget potential time zone issues.
Related
I needed to truncate milliseconds to seconds and implemented it in this way:
private static Long millisToSeconds(Long millisValue) {
return TimeUnit.MILLISECONDS.toSeconds(millisValue);
}
So now it truncates millis as expected, for example:
Long secondsValue = millisToSeconds(1554052265830L);
System.out.println("millisToSeconds ---> " + toSeconds);
// Prints millisToSeconds ---> 1554052265
But then I want to convert secondsValue to java.sql.Timestamp but the following implementation results in an error:
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
What should I fix in my implementation to convert seconds to timestamp so that the resulting timestamp looks like 2019-03-31 11:45:06 ?
java.time
I am assuming that you are asking for a java.sql.Timestamp for use with your SQL database. In most cases you shouldn’t ask for that. The Timestamp class is poorly designed and long outdated, and a modern JDBC driver or JPA implementation will be happy to accept a type from java.time, the modern Java date and time API, instead.
long millisValue = 1_554_052_265_830L;
Instant i = Instant.ofEpochMilli(millisValue);
i = i.truncatedTo(ChronoUnit.SECONDS);
System.out.println(i);
2019-03-31T17:11:05Z
I don’t know why you wanted to truncate to seconds, but you can see that it has been done (or it’s easy to leave that line out).
Some JDBC drivers accept an Instant directly when you pass it to PreparedStatement.setObject (one of the overloaded versions of that method) even though the JDBC specification doesn’t require this. If yours doesn’t, use an OffsetDateTime instead. Convert like this:
OffsetDateTime odt = i.atOffset(ZoneOffset.UTC);
System.out.println(odt);
2019-03-31T17:11:05Z
You can see that the value is still the same, only the type is different.
What should I fix in my implementation to convert seconds to timestamp
so that the resulting timestamp looks like 2019-03-31 11:45:06 ?
First, as I said, you should fix your code not to require a Timestamp, but also you are asking the impossible. As far as I know, Timestamp.toString would always produce at least one decimal on the seconds, so it would at least look like 2019-03-31 11:45:06.0.
If you do indispensably need a Timestamp for a legacy API that you cannot or don’t want to change just now, convert the Instant from before:
Timestamp ts = Timestamp.from(i);
System.out.println(ts);
2019-03-31 19:11:05.0
Don’t be fooled by the time looking different (19:11 instead of 17:11). Timestamp prints in my local time zone, which is Europe/Copenhagen, 2 hours ahead of UTC since summer time (DST) began on March 31. So we have still got the same point in time.
Link: Oracle tutorial: Date Time explaining how to use java.time.
You can use SimpleDateFormatto format the date as per your requirement. See below
Long secondsValue = millisToSeconds(1554052265830L);
System.out.println("millisToSeconds ---> " + secondsValue);
Timestamp timeStamp = new Timestamp(secondsValue);
String formattedDate = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(timeStamp.getTime());
System.out.println(formattedDate);
The error suggest that you are using Timestamp.valueOf(String) (possibly with secondsValue.toString() as the argument?).
A java.sql.Timestamp is a special version of java.util.Date with nanosecond precision to serialize/deserialize SQL TIMESTAMP values. It is not a second value at all.
The constructor of Timestamp take a millisecond value, not a second value (for nanosecond precision, you need to use the separate setNanos with the sub-second nanoseconds).
In any case the proper way would be to use:
long milliseconds = ...;
long seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds);
long truncatedMilliseconds = TimeUnit.SECONDS.toMillis(seconds);
// or truncatedMilliseconds = (milliseconds / 1000) * 1000;
Timestamp value = new Timestamp(truncatedMilliseconds);
However, since you are talking about needing a specific string format, I'm not sure you need this at all. Unless you are using JDBC to store this value in a database, you should not be using java.sql.Timestamp at all (and even when using JDBC, then it would probably be better to use java.time.LocalDatetime instead).
I am trying to get the difference between the current time and the time which is stored in DB.
I tried below code but its not giving the correct result since java.lang.System.currentTimeMillis() returns
UTC time whereas we save date to our application in EST format.
Code :
java.lang.System.currentTimeMillis() - emp.getModifiedDate()
Could you please suggest me a correct way to do it ?It will be very helpful for me
Thanks
System.currentTimeMillis() returns the number of milliseconds since January 1, 1970 UTC. It is time-zone agnostic.
If you are storing the time in the database as millis then simply subtracting the two numbers will give you the correct difference.
If you are storing the time in some other way (e.g. as a String), you can parse it (e.g. with SimpleDateFormat) to take into account the time zone and then obtain a Date from which you can obtain the millis.
Hope this helps! This will give you difference in no of days.
Date date1 = new Date();
long diff = date1.getTime() - emp.getModifiedDate().getTime();
System.out.println((int) (diff) / (1000 * 60 * 60 * 24)));
For more read this
My Objective is
to create a java class that can handle the below two requirements
(A) 1. Verify if the format of a timestamp matches with expected format.
CCYY-MM-DD'T'hh:mm:ss'.0000000000+'uh:um"
Ex: the expected format
is not static. It may be either of these
"2013-09-10T18:30:20.123456+10:00" or
"2013-09-10T18:30:20.123+10:00".
I am not bothered about the
precision and value. Only the format matters.
(B) 2. Verify if the timestamp is in a certain range.
Ex: Verify if the timestamp is in between "2013-09-10 18:27" and "2013-09-10 18:33". (verification is only upto minute level precision) (may be a delta of + or - 2min)
The question on first objective was posted here
Java : Custom Timestamp Format : verify format to microsec precision
In refrence to the second objective :
The Question :
How to verify if the timestamp is within the given range to minute precision using Java class?
The inputs to the class will be three arguments
The timestamp to be verfied as a string
The lower range timestamp as string
the higer range timestamp as string.
I tried this
String date = "2013-09-10T18:30:12.123456789+10:00"
SimpleDateFormat df2 = new SimpleDateFormat("yyyyMMddHHmm");
date = date.substring(0,22)+"+10:00";
Date newDate = df.parse(date);
timestamp_value = df2.format(newDate);
timestamp_value is now 201309101830
Check if timestamp_value is greater than 201309101827.
Check if timestamp_value is lesser_ than 201309101833
This is okay.
However, i feel this i a crude way of achieving it, so I would like to know if there is any better solution.
If i could convert to Timestamp object, i think .before and .after can help. Any suggestions ?
1) "2013-09-10T18:30:20.123+10:00" is XSD dateTime format and the best way to parse it is this
XMLGregorianCalendar xgc = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(date);
if date format is wrong IllegalArgumentException will be thrown
2) to verify if a timestamp is within a certain range the easiest way is to get millis from dates, truncate to minutes and use arithmetic comparison t >= from - delta && t <= to + delta
In my web app, date & time of a user's certain activity is stored(in database) as a timestamp Long which on being displayed back to user needs to be converted into normal date/time format.
(Actually my database Cassandra stores the timestamp of when a column was written to it, as a long value( microseconds since 1970 ) which I will use to find out the time of that corresponding user activity)
I am using JSF 2.0(+ primefaces) which I believe has converters that may be helpful for this conversion? Or otherwise how How can I, at best, achieve these conversions?
Let me propose this solution for you. So in your managed bean, do this
public String convertTime(long time){
Date date = new Date(time);
Format format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(date);
}
so in your JSF page, you can do this (assuming foo is the object that contain your time)
<h:dataTable value="#{myBean.convertTime(myBean.foo.time)}" />
If you have multiple pages that want to utilize this method, you can put this in an abstract class and have your managed bean extend this abstract class.
EDIT: Return time with TimeZone
unfortunately, I think SimpleDateFormat will always format the time in local time, so we can't use SimpleDateFormat anymore. So to display time in different TimeZone, we can do this
public String convertTimeWithTimeZome(long time){
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
return (cal.get(Calendar.YEAR) + " " + (cal.get(Calendar.MONTH) + 1) + " "
+ cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":"
+ cal.get(Calendar.MINUTE));
}
A better solution is to utilize JodaTime. In my opinion, this API is much better than Calendar (lighter weight, faster and provide more functionality). Plus Calendar.Month of January is 0, that force developer to add 1 to the result, and you have to format the time yourself. Using JodaTime, you can fix all of that. Correct me if I am wrong, but I think JodaTime is incorporated in JDK7
java.time
ZoneId usersTimeZone = ZoneId.of("Asia/Tashkent");
Locale usersLocale = Locale.forLanguageTag("ga-IE");
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(usersLocale);
long microsSince1970 = 1_512_345_678_901_234L;
long secondsSince1970 = TimeUnit.MICROSECONDS.toSeconds(microsSince1970);
long remainingMicros = microsSince1970 - TimeUnit.SECONDS.toMicros(secondsSince1970);
ZonedDateTime dateTime = Instant.ofEpochSecond(secondsSince1970,
TimeUnit.MICROSECONDS.toNanos(remainingMicros))
.atZone(usersTimeZone);
String dateTimeInUsersFormat = dateTime.format(formatter);
System.out.println(dateTimeInUsersFormat);
The above snippet prints:
4 Noll 2017 05:01:18
“Noll” is Gaelic for December, so this should make your user happy. Except there may be very few Gaelic speaking people living in Tashkent, so please specify the user’s correct time zone and locale yourself.
I am taking seriously that you got microseconds from your database. If second precision is fine, you can do without remainingMicros and just use the one-arg Instant.ofEpochSecond(), which will make the code a couple of lines shorter. Since Instant and ZonedDateTime do support nanosecond precision, I found it most correct to keep the full precision of your timestamp. If your timestamp was in milliseconds rather than microseconds (which they often are), you may just use Instant.ofEpochMilli().
The answers using Date, Calendar and/or SimpleDateFormat were fine when this question was asked 7 years ago. Today those classes are all long outdated, and we have so much better in java.time, the modern Java date and time API.
For most uses I recommend you use the built-in localized formats as I do in the code. You may experiment with passing SHORT, LONG or FULL for format style. Yo may even specify format style for the date and for the time of day separately using an overloaded ofLocalizedDateTime method. If a specific format is required (this was asked in a duplicate question), you can have that:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss, dd/MM/uuuu");
Using this formatter instead we get
05:01:18, 04/12/2017
Link: Oracle tutorial: Date Time explaining how to use java.time.
Not sure if JSF provides a built-in functionality, but you could use java.sql.Date's constructor to convert to a date object: http://download.oracle.com/javase/1.5.0/docs/api/java/sql/Date.html#Date(long)
Then you should be able to use higher level features provided by Java SE, Java EE to display and format the extracted date. You could instantiate a java.util.Calendar and explicitly set the time: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#setTime(java.util.Date)
EDIT: The JSF components should not take care of the conversion. Your data access layer (persistence layer) should take care of this. In other words, your JSF components should not handle the long typed attributes but only a Date or Calendar typed attributes.
To show leading zeros infront of hours, minutes and seconds use below modified code. The trick here is we are converting (or more accurately formatting) integer into string so that it shows leading zero whenever applicable :
public String convertTimeWithTimeZome(long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
String curTime = String.format("%02d:%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
return curTime;
}
Result would be like : 00:01:30
I tried this and worked for me.
Date = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0))).TotalSeconds
i have a time stamp coming in my XML that i put into my database.
The time stamp is in the format of number of seconds gone by since 1970.
i want to convert that into a date object.
how do i go about it?
thank you in advance.
You can create a Date instance based on the number of milliseconds since Jan 1, 1970. Your value is expressed in seconds, but that a trivial conversion:
long timestamp = getTimestampInSeconds(); // some megic to get the value
Date date = new Date(timestamp * 1000); // convert to milliseconds
Date class has special constructor for this:
Date result = new Date(numberOfSec * 1000);
Further you can format your Date object as you like using SimpleDateFormat.
See the doc.
It's been awhile since the question been asked, but i just faced the same trouble.
And I found out that the trouble is in the variable type. Are you using integer to store the timestamp value? Try using long. It worked for me