My program reading data from a database and I want to convert some fields to date format (date and time separately). I can do this from sql query but is it possible to do from java code.
date format in table = MMDDHHMISS (month day hour minute sec)
and these are sql queries now I'm using-
TO_CHAR(TO_DATE(DATETIMECOLUMN, 'MMDDHH24MISS'),'DD/MM/YYYY') AS MY_DATE
TO_CHAR(TO_DATE(DATETIMECOLUMN, 'MMDDHH24MISS'),'HH24:MI:SS') AS MY_TIME
Thanks in advance!
Here’s a suggestion:
DateTimeFormatter databaseStringFormatter = DateTimeFormatter.ofPattern("MMddHHmmss");
String sampleDatabaseString = "1129225145";
MonthDay myDate = MonthDay.parse(sampleDatabaseString, databaseStringFormatter);
LocalTime myTime = LocalTime.parse(sampleDatabaseString, databaseStringFormatter);
System.out.println("Date: " + myDate + ". Time: " + myTime + '.');
The above prints
Date: --11-29. Time: 22:51:45.
MonthDay is a date without a year, useful for birthdays and other anniversary dates.
Unless there are specific reasons to avoid it, I think you should rather change the datatype of your database column to datetime or similar and then retrieve LocalDateTime objects from your result set as shown in this answer. This would free you from any conversion from string to date and time in either the database query or in Java.
Related
I want a DateFormatter in java so that i can specify some special character as well as digits in a date expression. For ex :
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
Here dd is used to specify the day of month which is numeric.
But i have a requirement to create a date as below :
String stringDate = "2017-12-??T00:00Z";
SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
formatter.parse(stringDate);
I get an unparseable exception as the DAY specified here is ?? . Is there any workaround for this or shall i have to write a new parser ?
Thanks
Try escaping the additional literals using single quote
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-'??T'HH:mm:ss.SSS zzz");
Also the value and the format given should match(Can edit the string date as required), in your case following syntax will work.
String stringDate = "2017-12-??T00:00Z";
Date date = (new SimpleDateFormat("yyyy-MM-'??T'HH:mmZ")).parse(stringDate.replaceAll("Z$", "+0000"));
System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'??T'HH:mmZ")).format(date));
Please note that 'Z' indicates that the timezone conforms to the RFC 822 time zone standard as well.
Edit: Consider a scheduler. Your comment may sound like what you need is a scheduler, for example Quartz scheduler. I include a link at the bottom. Then convert user input not to a YearMonth, OffsetDateTime or any other date-time object (because they don’t fit), but into a syntax that your scheduler can accept.
Original answer
I am giving you a couple of suggestions. It’s with reservation though: I don’t understand why you want this, not even exactly what you want, so these suggestions may not be the right ones for you.
One suggestion I am pretty sure of, though: do use java.time, the modern java date and time API, for your date and time work. It is so much nicer to work with than the old, poorly designed and long outdated date-time classes that include the notoriously troublesome SimpleDateFormat class.
Parsing year and month: If you just want the year and the month from a string that has question marks instead of the day of month, parse into a YearMonth:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-'??T'HH:mmX");
String stringDate = "2017-12-??T00:00Z";
YearMonth ym = YearMonth.parse(stringDate, formatter);
System.out.println("Year and month are " + ym);
Output from this snippet is:
Year and month are 2017-12
Parsing all information from the string: If you need time of day and offset from the same string too, just parse the string once and get the various information from the parse result:
TemporalAccessor parsed = formatter.parse(stringDate);
YearMonth ym = YearMonth.from(parsed);
System.out.println("Year and month are " + ym);
LocalTime time = LocalTime.from(parsed);
System.out.println("Time of day is " + time);
ZoneOffset offset = ZoneOffset.from(parsed);
System.out.println("UTC offset is " + offset);
Year and month are 2017-12
Time of day is 00:00
UTC offset is Z
Using a default day of month: If you know what day of month you want instead of the question marks, specify it as a default value:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-'??T'HH:mmX")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
.toFormatter();
String stringDate = "2017-12-??T00:00Z";
OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z
Accepting both numbers and question marks: If the date can be given as either numeric or question marks, use optional parts in the format pattern strings. Such are enclosed in square brackets:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-[??][dd]'T'HH:mmX")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
.toFormatter();
String stringDate = "2017-12-??T00:00Z";
OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
System.out.println("Date and time is " + dateTime);
stringDate = "2018-02-16T00:00Z";
dateTime = OffsetDateTime.parse(stringDate, formatter);
System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z
Date and time is 2018-02-16T00:00Z
Tutorial links
Cron Trigger Tutorial from the Quartz Scheduler documentation.
Oracle tutorial: Date Time explaining how to use java.time.
I am having this problem with the conversion of string to date, I want to insert into the database date of format "dd.MM.yy" using this code:
SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
String d = f.format(new Date());
System.out.println("String: " + d);
Date d1 = f.parse(d);
System.out.println("Date: " +d1);
Output:
String: 16.06.17
Date: Fri Jun 16 00:00:00 EEST 2017
I tried other methods but the date is always printing in this format "EE MMM dd HH:mm:ss z yyyy".
Your code is working fine. Date class overrides the .toString() method so when you do System.out.println("Date: " +d1) you're actually doing System.out.println("Date: " + d1.toString());
If you want to print your date with the format you provide you'll need to use format() from your SimpleDateFormat:
SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
String d = f.format(new Date());
System.out.println("String: " + d);
Date d1 = f.parse(d);
System.out.println("Date: " + f.format(d1));
dd.MM.YY is not a valid sql type date. So you can not use this format directly to your database. If it is required you can use an alternative by making database field as varchar so it can accept your formatted date.And when you want to use this date you can simply format back this.
// For example retrieved from database.
String date = "2012/12/12";
SimpleDateFormat f = new SimpleDateFormat("dd.MM.yy");
Date newDate = f.format(new Date(date)); // Will hold date 12.12.12
Excuse me, but you are doing a number of things wrong.
While displaying two-digit years to the user is OK in situations where the century in unambiguous, you should never store two-digit years to your database. You are creating another Y2K problem. If you want to store years as string, store four digits.
But don’t store strings. Your RDBMS no doubt has a date datatype exactly made for and suited for storing dates. Use it instead.
In Java don’t use the long outdated classes SimpleDateFormat and Date. Their replacements came out in 2014. So use LocalDate for dates. Get a new JDBC driver (it should be JDBC 4.2 compliant) and store your LocalDate directly into the date typed column of your database. No need for any formatting.
In case you need to display your date to the user in dd.MM.yy format, use DateTimeFormatter:
LocalDate myDate = LocalDate.of(2017, Month.JUNE, 16);
System.out.println("The date is "
+ myDate.format(DateTimeFormat.ofPattern("dd.MM.yy")));
(I have not tested; if there’s a typo you cannot fix yourself, please revert.)
PS
the date is always printing in this format "EE MMM dd HH:mm:ss z yyyy".
Yes, java.util.Date prints that way. Always. A Date object does not hold a format in it (the same holds true for LocalDate). This has been explained in many places. See for example All about java.util.Date, scroll down to the section How do I convert a Date to a different format?
I know that there are tons of different tutorials on time conversion, but this one got me very confused. My task is to read UTC DATE from Oracle DB and convert it into BST time (in a more human readable format).
Facts:
Field in the DB is of DATE type.
When i perform SELECT query it returns 2011-07-12 15:26:07 result.
I'm located in Poland, hence in July the TimeZone here is UTC+2
What's happening:
On the Java side I'm using "classical" JDBC connection to the DB.
When I perform Timestamp timestampDate = resultSet.getTimestamp(COLUMN_NAME) I get the result ... but ...
System.out.println(timestampDate) prints to the console 2011-07-12 15:26:07.0 (which is similar to what I see in the DB tool.
System.out.println(timestampDate.getTime()); prints to the console 1310477167000 (which is wondering, because according to the ms to date converter i found online, it's basically 2011-07-12 13:26:07.0 (2h earlier - which somehow might be related to Polish timezone on that date)
When I perform conversion according to this code:
ukDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ukDateFormatter.setTimeZone(TimeZone.getTimeZone("BST"));
return ukDateFormatter.format(timestampDate.getTime());
I get 2011-07-12 19:26:07 which I can't really explain.
I was also trying this
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(timestampDate);
calendar.setTimeZone(TimeZone.getTimeZone("BST"));
return ukDateFormatter.format(calendar.getTime());
with the same result.
Question
How to properly read DATE from Oracle DB in "timezone agnostic" format and convert it into BST?
Here's a way of doing it in the database side:
with dates as (select to_date('01/07/2016 10:39:29', 'dd/mm/yyyy hh24:mi:ss') dt from dual union all
select to_date('01/02/2016 09:18:41', 'dd/mm/yyyy hh24:mi:ss') dt from dual)
select dt,
cast(dt AS TIMESTAMP) utc_dt_ts,
from_tz(cast(dt AS TIMESTAMP), 'UTC') AT time zone 'Europe/London' dt_as_ts_bst,
cast(from_tz(cast(dt AS TIMESTAMP), 'UTC') AT time zone 'Europe/London' AS DATE) dt_at_bst
from dates;
DT UTC_DT_TS DT_AS_TS_BST DT_AT_BST
------------------- ------------------------------------------------- ------------------------------------------------- -------------------
01/07/2016 10:39:29 01-JUL-16 10.39.29.000000 01-JUL-16 11.39.29.000000 EUROPE/LONDON 01/07/2016 11:39:29
01/02/2016 09:18:41 01-FEB-16 09.18.41.000000 01-FEB-16 09.18.41.000000 EUROPE/LONDON 01/02/2016 09:18:41
The fourth column (dt_at_bst) is the one that shows how to take the date and turn it into another date at BST. It does this by first casting the date as a timestamp and then telling Oracle to treat it as a timestamp at UTC and to output the timestamp for the 'Europe/London' region. Specifying the region like this (rather than passing a specific +01:00 timezone) means that the resultant timestamp will be daylight savings aware. Specifying the region as a three letter shortcut is not advised since that may represent more than one region - e.g. BST could be British Summer Time or Bering Standard Time; both very different things!
I have assumed that by BST you mean British Summer Time, so I have specified the region for the timestamp to be moved to as Europe/London. You would need to adjust this as applicable, if you need a different timezone.
I have included a winter and a summer date in my sample data to show you the effects of casting it into BST - the summer time is expecting to be changed, and the winter time is not.
Actually it is not about Oracle, but more about Java.
First of all:
When you use
System.out.println(timestampDate)
in output you see already adjusted time to your computer time zone.
It is always adjusted when you use Date (i.e.
Calendar.getTime() or Timestamp.getTime())
Code to play with:
SimpleDateFormat dtFmt = new SimpleDateFormat("HH:mm:ss");
NumberFormat nFmt = NumberFormat.getIntegerInstance();
nFmt.setMinimumIntegerDigits(2);
long currentTimeMs = System.currentTimeMillis();
GregorianCalendar utcCalendar = new GregorianCalendar(
TimeZone.getTimeZone("UTC"));
GregorianCalendar bstCalendar = new GregorianCalendar(
TimeZone.getTimeZone("Europe/London"));
GregorianCalendar localCalendar = new GregorianCalendar();
utcCalendar.setTimeInMillis(currentTimeMs);
bstCalendar.setTimeInMillis(currentTimeMs);
localCalendar.setTimeInMillis(currentTimeMs);
System.out.println("---- milliseconds ----");
System.out.println("Current ms : " + currentTimeMs);
System.out.println("Local Calendar ms: " + localCalendar.getTimeInMillis());
System.out.println("UTC Calendar ms: " + utcCalendar.getTimeInMillis());
System.out.println("BST Calendar ms: " + bstCalendar.getTimeInMillis());
System.out.println("---- SimpleFormat Time ----");
System.out.println("Current Time: "
+ dtFmt.format(new Date(currentTimeMs)));
System.out.println("Local Time: " + dtFmt.format(localCalendar.getTime()));
System.out.println("UTC Time : " + dtFmt.format(utcCalendar.getTime()));
System.out.println("BST Time : " + dtFmt.format(bstCalendar.getTime()));
System.out.println("---- Calendar Zone Time ----");
System.out.println("Local Zone Time: "
+ nFmt.format(localCalendar.get(Calendar.HOUR_OF_DAY)) + ":"
+ nFmt.format(localCalendar.get(Calendar.MINUTE)) + ":"
+ nFmt.format(localCalendar.get(Calendar.SECOND)));
System.out.println("UTC Zone Time : "
+ nFmt.format(utcCalendar.get(Calendar.HOUR_OF_DAY)) + ":"
+ nFmt.format(utcCalendar.get(Calendar.MINUTE)) + ":"
+ nFmt.format(utcCalendar.get(Calendar.SECOND)));
System.out.println("BST Zone Time : "
+ nFmt.format(bstCalendar.get(Calendar.HOUR_OF_DAY)) + ":"
+ nFmt.format(bstCalendar.get(Calendar.MINUTE)) + ":"
+ nFmt.format(bstCalendar.get(Calendar.SECOND)));
}
As you will see each Calendar returns Time fields (HOUR_OF_DAY, MINUTE, SECOND) according to its TimeZone, not what you print or format from Calendar.getTime())
What I did, and it seems to be working for me:
ukDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ukDateFormatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
and performing:
Timestamp timestampDate = rs.getTimestamp(...);
DateTime dateTime = new
DateTime(timestampDate).withZoneRetainFields(DateTimeZone.UTC);
System.out.println(ukDateFormatter.format(dateTime.getMillis()));
prints:
2011-07-12 16:26:07 from the input 2011-07-12 15:26:07
Why happened here?
What was so problematic here, is that rs.getTimestamp(...) was returning the date from the database "as it is" (since DATE column type doesn't preserve the timezone) implicitly but was adding some information about my local timezone - which I didn't wanted.
Easiest solution was to use joda and create new object, retaining values, but changing timezone to UTC. From that point conversion with SimpleDateFormat is quite straightforward.
I am storing my 2 Java date types as Date and Time for a MySQL database table. I am using the SimepleDateFormat("YYYY-MM-dd") to store the date in my database and it shows up as the correct date when i go to select it. However when i try to parse it back into a util.Date and create a new Event Object, it shows up as 30/12/2012 instead of 31/05/2013 as it is in the database. The time, when parsed into a util.Date and formatted prints out correctly. I am not sure why the Date is printing the wrong date, but the time is printing the correct time.
Database
+--------+--------------+-----------+
+ EVENT1 + 2013-05-31 + 02:30:00 +
+--------+--------------+-----------+
+ EVENT2 + 2013-05-31 + 01:00:00 +
+--------+--------------+-----------+
Prints:
Event1
30/12/2012
02:30
Event2
30/12/2012
01:00
It should be yyyy-MM-dd with lower case Ys. See here for what the capital Y means...
Y returns 2012 while y returns 2011 in SimpleDateFormat
Your pattern is wrong. (mm != MM, yyyy != YYYY ...)
Take a look at http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
try
String testDate = "2007-11-02T14:46:03";
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = formatter.parse(testDate);
But better way to store in database is to use timestamp instead of storing date and time separately
The proper method is rs.getDate(int). Take a look at
http://docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html#getDate(int)
With that method you get a java.sql.Date and if you want to transform it to a java.util.Date take a look at this Converting java.sql.Date to java.util.Date
You can even do this
Date date = rs.getTimestamp(2);
By the way, is better to have your date object independent on the format you want to use to show it.
try this...
SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd");
Date date = dateFormat.parse(rs.getDate(2).toString());
java.util.Date date = new java.util.Date();
java.sql.Date today = new java.sql.Date(date.getTime()); //2012-03-23
java.sql.Time time = new java.sql.Time(date.getTime()); //02:32:46
PreparedStatement pst = null;
String queryString = "INSERT INTO PR_VISITOR(PRISONER_ID,VISITOR_NAME,FATHER_NAME,DOV,IN_TIME) VALUES (?,?,?,?,?)";
pst = connect.prepareStatement(queryString);
pst.setString(1, pr_id);
pst.setString(2, visit);
pst.setString(3, father);
pst.setDate(4, today);
pst.setTime(5, time);
int officerQuery = pst.executeUpdate();
if (officerQuery == 1) {
response.sendRedirect("/FYP3.4/prisonAdmin/visitor_out.jsp");
JOptionPane.showMessageDialog(null, "Visitor information registered !!", "Visitor Information", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "Unable to Add information !!", "Visitor Information", JOptionPane.ERROR_MESSAGE);
}
By using the above code i'm trying to insert the current date and time into table,which have the separate columns. When i'm executing the above query then it insert the todays date in the time IN_TIME field too.
EDIT
DATATYPE OF IN_TIME and DOV are DATE .
Need Help.. !!
Since DOV and IN_TIME is date you don't need to separate date and hour. The type date in Oracle holds date and time. I suggest you change your table to have just one date column.
To insert the current time you can use the Oracle's sysdate function:
INSERT INTO PR_VISITOR(PRISONER_ID,VISITOR_NAME,FATHER_NAME,DATETIME_COLUMN) VALUES (?,?,?,?,SYSDATE)
To format your output of the date value you can use the SimpleDateFormat class in Java or to_char in Oracle.
A DATE column in an Oracle database will always store both a day (i.e. March 22, 2012) and a time to the second (i.e. 3:30:00 PM). A java.sql.Date and a java.sql.Time store the day and time as well but to the millisecond.
It doesn't really make sense to have separate columns in Oracle for the day and for the time but particularly not where both columns are declared as DATE data types. It would be much more conventional to use a single column declared as a DATE. If you really wanted to, you could truncate the day so that it represents midnight on the current day and then store the time component as, say, an INTERVAL DAY TO SECOND. But that would generally add a fair amount of complexity to the system for very little gain.
You're much better off using oracle's 'systimestamp'. The reason being, if you're java code is running in one timezone, and oracle lives in another. Forcing your own Time object, could cause problems.
Do you really need separate fields for this? I would think just having a timestamp would be enough.
Use SimpleDateFormat. This is one way I have used it:
Date now = Calendar.getInstance().getTime());
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String date = df.format(now);
DateFormat tf = new SimpleDateFormat("HHmmss");
String time = tf.format(now);
Follow this,it will help both in java and oracle
create table datetime(date_time timestamp);
insert into datetime values (sysdate);
To get date:
select to_char(date_time,'DD-MON-YY') from datetime;
eg:12-JUL-12
To get month:
select to_char(date_time,'mm') from datetime;
eg:7
To get time:
select to_char(date_time,'HH24:MI:SS') from datetime;
eg:23:56:15
cheers!!