how to get client's time zone in java from HttpServletRequest? [duplicate] - java

This question already has answers here:
How to detect the timezone of a client?
(4 answers)
Closed 5 years ago.
When server and client are in different time zones, can i get client's time zone in java using HttpServletRequest?
I am trying to create an instance of 'Calender' using client's 'Locale' like this,
Calendar calendar = Calendar.getInstance(request.getLocale());
TimeZone clientTimeZone = calendar.getTimeZone();
But this is giving me Server's time zone only.
Is this method wrong?
Is there any other way to get Client's time zone in Server?

Unfortunately the time zone information's are not passed in HTTP request.
But there are a work around for this case.
Check this answer and this one. it may help you.

there are 2 ways we get browser's timezone from request object.
when you are making request from the browser add an parameter to request object using javascript. The below command gives browser's timezone:
Intl.DateTimeFormat().resolvedOptions().timeZone
using this command you will get an string representing timezone example "Pacific/Fakaofo,Pacific/Honolulu" you can get this time zone out of request object on server side using
String timezoneStr = request.getParameter("your_parameter_name");
passing this string to Timezone.getTimeZone(timezoneStr); will return timezone object for browser's time
Another way of doing so is get the zoneOffset from the request session. Session contains zoneOffset value in integer form you need to get your GMT time out of that. below is the sample:
public static String getGMTSignedZone(HttpServletRequest request)
{
String zoneOffset;
HttpSession session = request.getSession();
zoneOffset = (String)session.getAttribute("timezone");
if(zoneOffset != null && !zoneOffset.equals(""))
{
Integer zMinutes = Integer.valueOf(zoneOffset);
String sign = (zMinutes < 0) ? "+" : "-";
String hourString;
String minString;
if(zMinutes < 0)
{
zMinutes = zMinutes*(-1);
}
// hours 0 to 23
int hours = zMinutes/60;
if(hours > 23)
{
hours = hours/24;
}
if(hours < 10)
{
hourString = "0" + hours;
}
else
{
hourString = "" + hours;
}
//minute conversion
int minutes = zMinutes - (hours*60);
if(minutes < 10)
{
minString = "0" + minutes;
}
else
{
minString = "" + minutes;
}
return ("GMT" + sign + hourString + minString);
}
return zoneOffset;
}
return of above can be easily converted into Timezone using below code:
StringBuffer buffer = new StringBuffer("");
int absOffset = Math.abs(offset);
int hrs = absOffset/60;
int mins = absOffset%60;
buffer.append("GMT").append(offset > 0 ? "-" : "+").append(hrs < 10 ? "0" : "").append(hrs).append(":").append(mins < 10 ? "0" : "").append(mins);
String tzID = buffer.toString();
TimeZone tz = TimeZone.getTimeZone(tzID);
use any of these method's to get timezone and convert your calender object to defined timezone.
out of both the methods seconds dosen't requires any client side code but a lot of validation on server side, and first approach requires small changes on client side and small changes on server side. It is up to you what you prefer.

Related

How do I set a default time to my timepicker?

I have I time picker in my code and when I press the edit text it shows up and everything looks good but I want to set a default time for my time picker so when the user opens the time picker it will be shown a specific time like "3:34 am" as a default time for the user, how can I do that?. Any help will be appreciated. { you can use java and kotlin}
My time picker
private fun showTimePicker() {
picker = MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_12H)
.setHour(12)
.setMinute(0)
.setTitleText("حدد الموعد الذي تريدة")
.build()
picker.show(supportFragmentManager, "AdhanNotifacations")
picker.addOnPositiveButtonClickListener {
if (picker.hour > 12) {
fajrEditTxt.setHint(String.format("%02d", picker.hour - 12) + ":"
+ String.format("%02d", picker.minute) + " PM")
} else {
fajrEditTxt.setHint(String.format("%02d", picker.hour) + ":"
+ String.format("%02d", picker.minute) + " AM")
}
calender = Calendar.getInstance()
calender[Calendar.HOUR_OF_DAY] = picker.hour
calender[Calendar.MINUTE] = picker.minute
calender[Calendar.SECOND] = 0
calender[Calendar.MILLISECOND] = 0
}
}
You were almost there, just change the value of setHour and setMinute to the hour and minute you want respectively.
I made few changes to your code to show default time of 3:34am:
picker = MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_12H)
.setHour(3) //3 hour
.setMinute(34) //34 minutes, so 3:34am
.setTitleText("حدد الموعد الذي تريدة")
.build()
If you want to show hour in PM, just add 12 to the hour. For example:
setHour(15)// will show 3pm
Let me know if you have any questions. Thanks.
EDIT
If you want to show time in strict HH:MM format you can keep your code and go as-is. But if you do not wish to be strict, then use the following code:
For example, this will show 9:3PM instead of 09:03PM.
//removed unnecesarry String.format
if(picker.hour > 12){
fajrEditTxt.setHint((picker.hour - 12).toString() + ":" + (picker.minute).toString() + " PM")
}else{
fajrEditTxt.setHint((picker.hour).toString() + ":" + (picker.minute).toString() + " AM")
}
OP asked how to access time:
val time = if(picker.hour > 12){
String.format("%02d",picker.hour - 12) + ":" + String.format("%02d", picker.minute) + " PM"
}else{
String.format("%02d",picker.hour) + ":" + String.format("%02d", picker.minute) + " AM"
}
time //use time, its in HH:MM format
fajrEditTxt.setHint(time)
I'm not understanding what it is you're asking, but if you're trying to sort the times in the library, you could place the times in a list and then sort the list, or if you just want to compare the magnitude values of two different times with just a couple of lines of code, you could remove the time separators from the time strings, convert those values to numbers ( of your choice ) and compare. The numbers generated from the conversions have no real world values, but their magnitudes with respect to one another will always be valid.
Oh. Snippet editor does not support touch devices.
Ok then.
String time = "00:00";
time.replace( ":", "" );
Double d = Double.parseDouble( time );
So now you can do with d as you wish. As you can see you don't have to bother with whether any of the values are to great. If you're dealing with a pair of valid times it's their relative magnitudes that matters. Of course if the time is in 12 Hr format, you'll need to strip the time modifier ( A, a, P, p, Am, AM .... ) too.

Check if timestamp coming from DB is 2hrs ago or older

I want to compare a timestamp coming from db and see if it's 1 hr 59 minutes old or not,I have implemented the following code.Please review it and suggest changes:
private static final long TIME_LIMIT= 7199 * 1000;
private Token getTokenFromDB ()
{
InterfaceRequestResponseDAO.getInstance ().getEntityManager ().createNamedQuery (InterfaceRequestResponse.Queries.GET_TOKEN) //
.setParameter ("token", InterfaceRequestResponse.COL_RESPONSEEND)//
.setParameter ("interfaceRequestResponseID", this.getInterfaceRequestResponseID ())//
.executeUpdate ();
// authenticationToken.getResponseEnd ();
long responseEnd = System.currentTimeMillis ();
if (responseEnd < TIME_LIMIT)
return authenticationToken;
else
return NOT_VALID;
I suggest you to use JodaDate..
I implemented the same thing in a project. What I did was I saved the expire time instead of the timestamp created. This makes it more easy to handle.
Everytime I refresh the token, I update the expireTime by adding the offset
DateTime expireTime = new DateTime(new Date());
expireTime = expireTime.addHours(2);//because token expires in 2 hours
And then I store this time.
When I'm requesting, I used to check if the current time < expire time.
DateTime expireTime = getTimeFromDB();
DateTime now = new DateTime(new Date());
if( now.isBefore(expireTime))
{
//valid token.
}
else
{
// refresh your token and update the time.
}

What does Java's SimpleDateFormat make with milli/micro-seconds?

I have simple test
#SuppressWarnings("deprecation")
#Test
public void test_NO_MILLIS() throws ParseException {
String rabbit = "22-OCT-15 06.37.35";
final String PATTERN = "dd-MMM-yy HH.mm.ss";
Date dateObject = new SimpleDateFormat(PATTERN).parse(rabbit);
Assert.assertNotNull(dateObject);
Assert.assertEquals(22, dateObject.getDate());
Assert.assertEquals(10, dateObject.getMonth() + 1);
Assert.assertEquals(2015, dateObject.getYear() + 1900);
Assert.assertEquals(6, dateObject.getHours());
Assert.assertEquals(37, dateObject.getMinutes());
Assert.assertEquals(35, dateObject.getSeconds());
}
And everything goes right. I get 22 as day in result.
But after I am adding microseconds both to pattern and to string value to be parsed
#Test
public void test_MILLIS() throws ParseException {
String rabbit = "22-OCT-15 06.37.35.586173000";
final String PATTERN = "dd-MMM-yy HH.mm.ss.SSSSSSSSS";
Date dateObject = new SimpleDateFormat(PATTERN).parse(rabbit);
Assert.assertNotNull(dateObject);
Assert.assertEquals(22, dateObject.getDate());
Assert.assertEquals(10, dateObject.getMonth() + 1);
Assert.assertEquals(2015, dateObject.getYear() + 1900);
Assert.assertEquals(6, dateObject.getHours());
Assert.assertEquals(37, dateObject.getMinutes());
Assert.assertEquals(35, dateObject.getSeconds());
}
I get an assert failure
junit.framework.AssertionFailedError: expected:<22> but was:<29>
at junit.framework.Assert.fail(Assert.java:57)
at junit.framework.Assert.failNotEquals(Assert.java:329)
at junit.framework.Assert.assertEquals(Assert.java:78)
at junit.framework.Assert.assertEquals(Assert.java:234)
at junit.framework.Assert.assertEquals(Assert.java:241)
at main.TestDateFormatTest.test_MILLIS(TestDateFormatTest.java:36)
...
Which means that day has become 29 instead of 22. What has gone wrong?
Tested
Platforms: mac osx 10.9, ubuntu, win7
jdk: 7,6
The format pattern S for milliseconds doesn't take into account mathematical placement values; it just sees 586173000 as the number of milliseconds to add to the rest of the date. That number is equivalent to about 6.784 days, so that explains why the date became 29 instead of 22.
Before parsing, cut off the milliseconds at 3 digits, e.g. "22-OCT-15 06.37.35.586", so it's interpreted as 586 milliseconds.

Conversion from "datetime-local" to java.sql.Timestamp

I have a form with input of type "datetime-local" on a jsp page, the data is passed to a servlet:
String resetTimeString = request.getParameter(RequestParameterName.RESET_TIME);
How to convert the input to java.sql.Timestamp?
EDIT:
Well, I found something new!
You can use Timestamp.valueOf() to format a time-string with the value of yyyy-[m]m-[d]d hh:mm:ss[.f...]
So it can also handle micro/nano seconds. The only thing you need to do is replace the T with a space.
This works:
String datetimeLocal = "1985-04-12T23:20:50.52";
System.out.println(Timestamp.valueOf(datetimeLocal.replace("T"," ")));
The output:
1985-04-12 23:20:50.52
According to this site your resetTimeString looks like this: '1985-04-12T23:20:50.52' (a string)
I couldn't find a method to convert this to a timestamp directly, but you could just split it up manually:
String[] dateTime = datetimeLocal.split("T");
String[] date = dateTime[0].split("-");
String[] time = dateTime[1].split(":");
This will print:
System.out.println("DateTime: " + Arrays.toString(dateTime));
System.out.println("Date: " + Arrays.toString(date));
System.out.println("Time: " + Arrays.toString(time));
>>> DateTime: [1985-04-12, 23:20:50]
>>> Date: [1985, 04, 12]
>>> Time: [23, 20, 50]
After that you could just create a new Timestamp: (This is deprecated!)
Timestamp stamp = new Timestamp(Integer.valueOf(date[0]).intValue() - 1900,
Integer.valueOf(date[1]).intValue(),
Integer.valueOf(date[2]).intValue(),
Integer.valueOf(time[0]).intValue(),
Integer.valueOf(time[1]).intValue(),
Integer.valueOf(time[2].split("\\.")[0]).intValue(),
Integer.valueOf(time[2].split("\\.")[1]).intValue());
Note that, if you use this you need to subtract '1900' from the year and split dots with \\.
Also, you'd need to handle nanoseconds (In my example I'm using the value 50.52 as seconds, but the string returned from your server might not contain the nanoseconds)
You could also calculate a long from the date and use new Timestamp(<long>)
I hope this helps :)
Cyphrags' answer won't work if seconds are set to "00", because Chrome won't send the seconds part resulting in a java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff] when calling Timestamp.valueOf().
Therefore a more complete answer could be:
String datetimeLocal = "1985-04-12T23:20";
// make sure the seconds are set before parsing
if (StringUtils.countMatches(datetimelocal, ":") == 1) {
datetimelocal += ":00";
}
Timestamp value = Timestamp.valueOf(datetimeLocal.replace("T", " "));

Get actual time (java, c) synchronized

i am working on easy game(just for fun).
I have server in c and client in java.
I want get actual time on server and on client, but I can not come to the same results time.
On server i am using:
// the system time
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
// the current file time
FILETIME fileTime;
SystemTimeToFileTime(&systemTime, &fileTime);
// filetime in 100 nanosecond resolution
ULONGLONG fileTimeNano100;
fileTimeNano100 = (((ULONGLONG) fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
//to milliseconds and unix windows epoche offset removed
ULONGLONG posixTime = fileTimeNano100 / 10000 - 11644473600000;
return posixTime;
And i am getting time in format(output): 1750721123
On client i am using
long lDateTime = new Date().getTime();
System.out.println("Date() - Time in milliseconds: " + lDateTime);
Calendar lCDateTime = Calendar.getInstance();
System.out.println("Calender - Time in milliseconds :" + lCDateTime.getTimeInMillis());
And i am gettin format(output):
Calender - Time in milliseconds :1419089968022
Date() - Time in milliseconds: 1419089968022
Why? Where is the problem? How can i get the same TIME?
Both programs run on the same pc(win 8.1)
First of all. First block of code doesn't seem to be standard C code at all or rather you use some libraries that I just simply doesn't know.
There is no simple way to get actual time with less than a second accuracy in standard C. But here is the example with Java and C that actually works, so I hope this would help.
Java
package stackOverflow;
import java.util.Date;
public class Main {
public static void main(String[] args) {
long lDateTime = new Date().getTime();
System.out.println(lDateTime/1000);
}
}
Output: 1436200408
C
#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<time.h>
int main(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("%ld\n", tv.tv_sec);
return 0;
}
Output: 1436200418

Categories