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

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.

Related

How to compare FTPClient File's last modification with a local file?

I have two files one in the server and one is local, I want to get the last modification of both files and see which one is newer. I made a method, but I always get the same result. I tried the test each side, but the if statement make the same decition always.
Here is my code:
public void SyncCheck(FTPClient ftpClient, String remoteFilePath, String savePath) throws IOException, ParseException{
String time = ftpClient.getModificationTime(remoteFilePath);
Date remoteFileDate = timeSplitter(time);
Date LocalFileDate = new Date(new File(savePath).lastModified());
if(remoteFileDate.after(LocalFileDate)){
System.out.println("Remote File is newer: " + remoteFileDate);
}
else{
System.out.println("nothing");
System.out.println("Remote " + remoteFileDate);
System.out.println("Local " + LocalFileDate);
}
}
public Date timeSplitter(String time) throws ParseException{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String timePart = time.split(" ")[1];
Date modificationTime = dateFormat.parse(timePart);
return modificationTime;
}
The result is always this:
nothing
Remote Fri Apr 03 02:20:30 BST 2015
Local Fri Apr 03 03:12:58 BST 2015
No matter is the remote file is newer or older. The other this I notices is that the remote file is modified at 03:20:30, but it is one hour behind always. Is is about anything with time zones?
Or any idea to compare last modification time of one server file vs. a local one ?
There is no standard way to know ftp server timezone, but what you can do is to upload a file and then calculate the time difference between the file time reported by FTP and locally. This must be a method running as a first step of your program to initialize the timezone logic in every client application of yours.

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

How to set weekend as work day in MPXJ

I am exporting project in MS Project via MPXJ library and I have one question:
How to set specific date Saturday (or Sunday) as work day instead of weekend? (in ProjectCalendar or in another place)
For example 2014 oct 18 (it is Saturday) set as working day, but another Saturdays need to be weekend.
public ProjectCalendar initCalendar(ProjectFile projectfile, int calendarId, Date startDate, Date endDate) {
ProjectCalendar defaultCalendar = projectfile.addDefaultBaseCalendar();
/*Setup standart working week*/
defaultCalendar.setName("Standart");
defaultCalendar.setWorkingDay(Day.MONDAY, DayType.WORKING);
defaultCalendar.setWorkingDay(Day.THURSDAY, DayType.WORKING);
defaultCalendar.setWorkingDay(Day.WEDNESDAY, DayType.WORKING);
defaultCalendar.setWorkingDay(Day.TUESDAY, DayType.WORKING);
defaultCalendar.setWorkingDay(Day.FRIDAY, DayType.WORKING);
defaultCalendar.setWorkingDay(Day.SATURDAY, DayType.NON_WORKING);
defaultCalendar.setWorkingDay(Day.SUNDAY, DayType.NON_WORKING);
ProjectCalendarHours pch;
pch = defaultCalendar.addCalendarHours(Day.MONDAY);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
pch = defaultCalendar.addCalendarHours(Day.THURSDAY);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
pch = defaultCalendar.addCalendarHours(Day.WEDNESDAY);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
pch = defaultCalendar.addCalendarHours(Day.TUESDAY);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
pch = defaultCalendar.addCalendarHours(Day.FRIDAY);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
/* setup holydays*/
List<Date> workingHollidays = DBHelper.getWorkingHolidays(ppmCalendarId, startDate, endDate);
for (Date work : workingHollidays) {
ProjectCalendarException ex = defaultCalendar.addCalendarException(work, work);
}
/*There is I need change stendart week and setup 6-days working week (Saturday is work day) */
/*something like that*/
Date workindDay = new SimpleDateFormat("dd.MM.yyyy").parse("18.10.2014");
defaultCalendar.setWorkingDay(workindDay, DayType.NON_WORKING); // This code not work
pch = defaultCalendar.addCalendarHours(workindDay); // This code not work
pch.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
pch.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
}
and in ountput Microsoft Project xml will be tag like this:
<Calendar>
...
<WeekDay>
<DayType>
0
</DayType>
<DayWorking>
1
</DayWorking>
<TimePeriod>
<FromDate>2014-10-18T00:00:00</FromDate>
<ToDate>2014-10-18T23:59:00</ToDate>
</TimePeriod>
<WorkingTimes>
<WorkingTime>
<FromTime>09:00:00</FromTime>
<ToTime>13:00:00</ToTime>
</WorkingTime>
<WorkingTime>
<FromTime>14:00:00</FromTime>
<ToTime>18:00:00</ToTime>
</WorkingTime>
</WorkingTimes>
</WeekDay>
...
</Calendar>
Thanks.
I found answer.
There is the code to make custom date as working date:
Date workindDay = new SimpleDateFormat("dd.MM.yyyy").parse("18.10.2014");
ProjectCalendarException ex = defaultCalendar.addCalendarException(workindDay, workindDay);
ex.addRange(ProjectCalendar.DEFAULT_WORKING_MORNING);
ex.addRange(ProjectCalendar.DEFAULT_WORKING_AFTERNOON);
Order of range is important.

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

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.

Categories