I tried to program date and time so that it corresponds to the current date but could not find a solution in the console, only the date of the last run is displayed. Here is my code:
public class DateDemo {
public static void main(String args[]) {
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat("E dd.MM.yyyy 'um' HH:mm:ss ");
System.out.println("Datum: " + ft.format(dNow));
}
}
Consoles behave differently, so I’m afraid that there isn’t any universal solution.
I tried this:
DateTimeFormatter formatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(Locale.GERMAN);
ZoneId timeZoneId = ZoneId.of("Europe/Zurich");
int totalIterations = Math.toIntExact(TimeUnit.HOURS.toSeconds(2));
for (int sec = 0; sec < totalIterations; sec++) {
System.out.print(ZonedDateTime.now(timeZoneId).format(formatter) + '\r');
TimeUnit.SECONDS.sleep(1);
}
When I run it inside Eclipse, it prints the lines under each other in the Eclipse console like this:
16. November 2019 07:37:32 MEZ
16. November 2019 07:37:33 MEZ
16. November 2019 07:37:34 MEZ
16. November 2019 07:37:35 MEZ
But when I run it from the Terminal window on my Mac, it stays on the same line and just keeps overwriting it:
The \rcharacter is a carriage return. In theory it should go back to the beginning of the same line. Maybe the reason why it doesn’t in Eclipse is they thought I wanted to use the console window for debugging and therefore would be better served if I could see all output, so they didn’t want to overwrite any. Just guessing.
There are more elegant and more accurate ways to make something happen every second. Look into ScheduledExecutorService.scheduleAtFixedRate.
PS The format differs a bit in the two screen shots, in the Terminal window um (“at”) is included between the date and the time. The difference comes from different Java versions. In Eclipse I used Java 8, in the Terminal window Java 11. The story is in this question: JDK dateformatter parsing DayOfWeek in German locale, java8 vs java9.
Related
I want the new Japanese ERA Date as "R010501", whereas I am getting "R151".
I am using the com.ibm.icu.text.DateFormat package to get the date format
Date dtEngDate = new SimpleDateFormat("yyyy-MM-dd").parse("2019-05-01");
com.ibm.icu.util.Calendar japaneseCalendar = new com.ibm.icu.util.JapaneseCalendar();
com.ibm.icu.text.DateFormat japaneseDateFormat = japaneseCalendar.getDateTimeFormat(
com.ibm.icu.text.DateFormat.SHORT, -1, Locale.JAPAN);
String today = japaneseDateFormat.format(dtEngDate);
System.out.println("today is:" +today.replaceAll("/", ""));
Output: today is --> R151.
Expected Output: today is --> R010501
I don't know what exactly you did other than me but I just downloaded the com.ibm.icu library from http://www.java2s.com/Code/Jar/c/Downloadcomibmicu442jar.htm and basically copied your code.
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.JapaneseCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
Date dtEngDate = new SimpleDateFormat("yyyy-MM-dd").parse("2019-05-01");
Calendar japaneseCalendar = new JapaneseCalendar();
DateFormat japaneseDateFormat = japaneseCalendar.getDateTimeFormat(DateFormat.SHORT, -1, Locale.JAPAN);
String today = japaneseDateFormat.format(dtEngDate);
System.out.println("today is: " + today.replaceAll("/", ""));
}
}
I'm getting today is: 平成310501 as console output and I guess this is what you are looking for. So I guess there is something wrong with your com.ibm.icu-4.4.2.jar.
Maybe consider retrying to download the latest version from the link I used and adding it to the modules/projects dependencies.
java.time.chrono.JapaneseDate
You don’t need an external dependency for the Japanese calendar. It’s built-in, in the JapaneseDate class.
Beware: Only the most recent versions of Java know about the new Reiwa era.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("GGGGGyyMMdd", Locale.JAPANESE);
LocalDate isoDate = LocalDate.parse("2019-05-01");
JapaneseDate japaneseDate = JapaneseDate.from(isoDate);
System.out.println(japaneseDate.format(dateFormatter));
Output from this snippet on Java 11.0.3 is:
R010501
Five pattern letters G gives the narrow form of the era, just one letter (here R for Reiwa).
On Java 9.0.4 I got H310501. So it seems that it will work correctly if you are able to upgrade your Java. Meno Hochschild reports in a comment that he got the correct result on Java 8u212, so you may not need to upgrade to a new major version if only you’ve got the newest minor upgrade within your major version. I don’t know if there’s a way to upgrade only the calendar data in an older Java version, it might be another thing to investigate.
BTW don’t use SimpleDateFormat and Date. Those classes are poorly designed (the former in particular notoriously troublesome) and long outdated. Use java.time, the modern Java date and time API. It’s so much nicer to work with.
Link: Oracle Tutorial: Date Time explaining the use if java.time.
I'm working with an agent java application and it is installed on several Windows machines in different places of the world. I would like periodically synchronize windows clock (Date and Time). I have already found the native command to set time in windows by java code:
Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss
or to execute
Runtime.getRuntime().exec("cmd /C date " + strDateToSet + "& time " + strTimeToSet);
But the main problem is focalizied on set date, because is possible that the date format on windows machines is not the same for all machines. For example I could have dd-MM-yy for Italian machine and yy-MM-dd for US machine. So if my application set the date with format dd-MM-yy wuold be wrong for US machine.
Knowing that I cant't use NTP (Machines into LAN with Firewall with out rules only protocol HTTPS port 443)
how can I set date correctly by java application for all windows machines ?
Which is the best solution both semplicity and maintainability ?
Note: Agent java application has already the timestamp to be set on windows machine passed by web service response, therefore is necessary only to do the setDateAndTime
TEST exec date command with format date yyyy-MM-dd on Windows (set wrong date):
I tried to implement the solution with JNA importing kernel32.dll performed the test on Windows 7 machine with timezone UTC+1 (Italy country).
I describe the steps:
1) I imported my maven project the followed dependencies:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.3.0</version>
</dependency>
2) I implemented the followed class:
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
import com.sun.jna.win32.StdCallLibrary;
#Component
#Qualifier("windowsSetSystemTime")
public class WindowsSetSystemTime {
/**
* Kernel32 DLL Interface. kernel32.dll uses the __stdcall calling
* convention (check the function declaration for "WINAPI" or "PASCAL"), so
* extend StdCallLibrary Most C libraries will just extend
* com.sun.jna.Library,
*/
public interface Kernel32 extends StdCallLibrary {
boolean SetLocalTime(SYSTEMTIME st);
Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32.dll", Kernel32.class);
}
public boolean SetLocalTime(SYSTEMTIME st) {
return Kernel32.instance.SetLocalTime(st);
}
public boolean SetLocalTime(short wYear, short wMonth, short wDay, short wHour, short wMinute, short wSecond) {
SYSTEMTIME st = new SYSTEMTIME();
st.wYear = wYear;
st.wMonth = wMonth;
st.wDay = wDay;
st.wHour = wHour;
st.wMinute = wMinute;
st.wSecond = wSecond;
return SetLocalTime(st);
}
}
3) By the test class I tried to set the followed date and time
public void setTime(){
System.out.println("START SYNC " + windowsSetSystemTime);
windowsSetSystemTime.SetLocalTime((short)2017, (short)10,(short) 29,(short) 11,(short) 35,(short) 0);
}
TEST RESULT:
As result in this case I obtained the correct date and time because the function considered daylight winter time saving that enter at 29 October 2017 3:00.
Before test, clock was set:
After test clock set:
I found out the logic SetLocalTime method into Kernel32.dll by Windows dev center documentation at link:
SetLocalTime documentation
Windows Dev center REMARKS SetLocalTime:
The system uses UTC internally. Therefore, when you call SetLocalTime, the system uses the current time zone information to perform the conversion, including the daylight saving time setting. Note that the system uses the daylight saving time setting of the current time, not the new time you are setting. Therefore, to ensure the correct result, call SetLocalTime a second time, now that the first call has updated the daylight saving time setting.
I found that Java gives incorrect time in MSK timezone, ignoring operating system data:
As you see, the Java time is hour ahead.
The code is follows:
package tests;
import java.util.Date;
public class Try_CurrentTime {
public static void main(String[] args) {
System.out.println(new Date());
}
}
java version is 1.8.0_25
We have no DST.
Is it possible to fix?
UPDATE
It doesn't think we have DST, because TimeZone.getDefault().inDaylightTime( new Date() ) returns false.
Refer to the Timezone Data Versions in the JRE Software chart. The change you are referring to was made in tzdata 2014f - which was first introduced in TZUpdater 1.4.6, or JRE 1.8 update 31. You said you are running 1.8 update 25.
Simply update your Java runtime to the current version.
My system time zone is (UTC+02:00) Istanbul. When I run a simple java program to display time zone, it displays "America/Rio_Branco" (which is incorrect). But when I set to any other time zones it works correctly. Also I updated my jre using tzupdater.jar (I set my path to ..\jre\lib). What could be the reason?
My code is :
import java.util.*;
import java.text.*;
public class Time
{
public static void main(String[] args){
TimeZone timeZone = TimeZone.getDefault();
System.out.println("timeZone : "+timeZone);
}
}
I replaced tzmappings file with the one from jre8 and it solved my problem.
If you read the JavaDoc you'll see this:
Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation.
Thus reason you're getting "America/Rio_Branco" is because the JDK implementation for your host (operating system) thinks you are in Rio Branco's timezone. In the comments you mention you're running Windows 7, so it might be the case that Windows incorrectly has a timezone set somewhere. I think Java on Windows checks in the registry here:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/TimeZoneInformation
Maybe you can check that value?
In order to test java-code with date / time set into the past or future I want to try libfaketime (currently we just adjust the system clock, but it causes much trouble like non working kerberos, etc).
I try with this small test program:
$ cat time.java
import java.util.*;
class TimeTest {
public static void main(String[] s) {
long timeInMillis = System.currentTimeMillis();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timeInMillis);
java.util.Date date = cal.getTime();
System.out.println("Date: " + date);
}
}
And executes this:
LD_ASSUME_KERNEL=2.6.18 LD_PRELOAD=/usr/lib64/libfaketime.so.1 FAKETIME="-15d" /opt/IBM/WebSphere/AppServer/java_1.7_64/bin/java TimeTest
Invalid clock_id for clock_gettime: -172402[root#myhost ~]#
But as you can see I just get an error message.
The test is performed on a RHEL 6.5 server, kernel 2.6.32-431 and
libfaketime 0.9.6
Do you have any suggestions how I can solve this? I'm also interested in hearing your experiences with libfaketime and java on RHEL.
I have also reported this issue at: https://github.com/wolfcw/libfaketime/issues
Best reagards,
Erling
I've observed this incorrect behaviour as well in IBM JVM 1.7.0 while in Oracle JVM 1.6.0 this works as expected.
The explanation is that IBM JVM apparatently has an internal bug which manifests by calling clock_gettime system call with incorrect clock_id parameter (random negative value).
The workaround (not a fix) is to modify libfaketime.c to reset the clock_id to valid value in fake_clock_gettime function.
case FT_START_AT: /* User-specified offset */
if (user_per_tick_inc_set)
{
/* increment time with every time() call*/
next_time(tp, &user_per_tick_inc);
}
else
{
if (clk_id < 0) { // jvm calls clock_gettime() with invalid random negative clock_id value
clk_id = CLOCK_REALTIME;
}
switch (clk_id)
// the rest is the same
This will prevent the libfaketime.so.1 library from existing on error you are observing
printf("\nInvalid clock_id for clock_gettime: %d", clk_id);
exit(EXIT_FAILURE);
Please note this workaround has a drawback that in case JVM is incorrectly asking system for invalid clockid, we will assume valid clockid which may be not what application expects.