I am storing date values within a SQLite database in the format 20121224 (so that I can easily sort the database by date) my question is how can I get the date from the format "20121224" to "2012/12/24" after being extracted from the database using java code.
You can do this.
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test003 {
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd");
String s = "20121224";
Date dt = sdf1.parse(s);
System.out.println(sdf2.format(dt));
}
}
private static final String DATE_FORMAT = "yyyy/MM/dd";
private static final SimpleDateFormat dateFormat = new
SimpleDateFormat(DATE_FORMAT);
public static long dateAsLong(Calendar cal){
return Long.parseLong(dateFormat.format(cal.getTime()));
}
public static Calendar dateAsCalendar(long l){
try {
Calendar c = Calendar.getInstance();
c.setTime(dateFormat.parse(String.valueOf(l)));
return c;
} catch (ParseException e) {
return null;
}
}
Hope this helps.
In Java, Strings are immutable, so you can't modify the String you get back from the database; you have to make a new one. Easiest way, if your dates are guaranteed to be in yyyyMMdd format (ie, you don't store January as "01"), and you just want another String to come out the other end:
StringBuilder date = new StringBuilder();
date.append(dateStr.substring(0,4));
date.append("/");
date.append(dateStr.substring(4,6));
date.append("/");
date.append(dateStr.substring(6,8));
// use date.toString() wherever you need it
However, I'd recommend looking into how SQLite recommends you store dates. These are common formats and will allow you to use Java's built-in Date and DateFormat class in more conventional and convenient ways.
I see someone else has beaten me to submitting an answer while I was typing this...that suggestion will work, but it has you constructing 2 SimpleDateFormat objects, which isn't necessarily the most efficient way to go. Depends on how often you're doing this.
You can use the strftime function
Syntax:
strftime(timestring, modifiers...)
This returns the date formatted according to the format string specified
Example:
SELECT strftime('%d-%m-%Y') from TABLE_NAME;
Output:
24-11-2013
You can find all the formatters here
Related
I'm trying to convert a resultset from ddMMyyyy HH:mm:ss (ex: 19/06/2022 00:00:10) to yyyyMMddHHmmss (should be 20220619000010) with SimpleDateFormate without success. This is how I'm doing:
I have an Util class, which has the follow class:
public class Utils {
public static String Format(String formato, Date date) {
date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String dataString = sdf.format(date);
return dataString;
}
}
And I also have a ResultSet class witch return the objects of my query based in another class. Example:
Class one:
public class MyFile {
String Date = new String ();
+ getter and setter
}
Class 2 (create the line of my document):
public static MyFile createRow (ResultSet rs) throws SQLException {
MyFile mf = new MyFile();
mf.setDate(Utils.Format(rs.getString("Date");
return mf;
}
The point is: This conversion doesn't work and I can't find another way to do this. Someone could help me, please?
The java message:
"The method Format(String, Date) in te type Utils is not applicable for the arguments (String)
3 quick fixes available:
+ add argument to match 'Format(String, Date)'
- Change method 'Format(String, Date)': Remove parameter 'Date'
º Create method 'Format(String) in type 'Utils'"
For the conversion, you'll need two SimpleDateFormats; one for parsing the string to date, another to turn the date to the desired format:
public static String Format(String formato, Date date) {
SimpleDateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
try {
date = new inputFormat.parse(formato);
} catch (ParseException ex) {
// wrong format?
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String dataString = sdf.format(date);
return dataString;
}
// usage
mf.setDate(Utils.Format(rs.getString("Date"), new Date()));
I presume your date parameter would be a default Date in case the formato input string is invalid.
If you want to do it with the packages java.time and java.time.format you can try something like this. Of course java.util.Date is stored essentially as milliseconds from the epoch without time zone, hence using UTC below. If you want the output to correspond to a particular time zone, then change it:
public static String formatDate(Date d) {
String result = null;
Instant i = Instant.ofEpochMilli(d.getTime());
ZonedDateTime zdt = ZonedDateTime.ofInstant(i, ZoneId.of("UTC"));
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
result = fmt.format(zdt);
return result;
}
First of all, I want to tell you that there are newer and more convenient libraries than the old java.util.Date library. I am not so experienced with the new ones, but mostly java.util.time (like here: Understanding Java util Date) or joda.time are recommended.
So maybe you want to consider using one of the newer library instead of the old SimpleDateFormat from java.util.Date, if you only just began coding with Dates and just picked the first library coming to your mind, I think it could be a good idea.
To your specific problem: The java error message just tells you how it is, in your utils class you have your String Format with the constructor with two input params, a String and a date. In this line:
mf.setDate(Utils.Format(rs.getString("Date");
you are calling your Utils.Format String, but you are only passing one argument, "rs.getString("Date")". So either you refactor your String Format Constructor to only take a string as an argument or you pass (like recommended in the java message) a string and a date, for instance like:
mf.setDate(Utils.Format(rs.getString("Date"), new Date();
While I'm writing this, I think in this line two closing brackets are missing. You should add them.
But I think it should not be that complicated to convert a String like 19/06/2022 00:00:10 into another format using SimpleDateFormat. All you need to do is
String sDate1="19/06/2022 00:00:10";
SimpleDateFormat formatter1=new SimpleDateFormat("yyyyMMddHHmmss");
Date date1=formatter1.parse(sDate1);
This way, in date1 should be your DateString in the Format you specified when initialising your SimpleDateFormat formatter1.
Here is the official doc to SimpleDateFormat: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Thnx for your answers, but I couldn't make any work.
So, I tried another way with success. It is:
public static String Format (String date) {
String formattedDate= date.substring(0, 4)
+ date.substring(5, 7)
+ date.substring(8, 10)
+ date.substring(11, 13)
+ date.substring(14, 16)
+ date.substring(17, 19);
return formattedDate;
}
mf.setDate(Utils.Format(rs.getString("Date");
This question already has answers here:
Get first date of current month in java
(11 answers)
Closed 4 years ago.
I can convert a String to a Date:
private static final SimpleDateFormat CARD_DATE_FORMAT = new SimpleDateFormat("yyMMdd", Locale.getDefault());
public static Date toCardDateFormat(String date){
try {
return CARD_DATE_FORMAT.parse(date);
} catch (ParseException e) {
return null;
}
}
For example I have 200908 - it will convert to 2020-09-08, but I need set the day always to 1st day of month. I need 2020-09-01. How can I make this?
According to your need,you can use this method:
private static final SimpleDateFormat CARD_DATE_FORMAT = new SimpleDateFormat("yyMMdd", Locale.getDefault());
public static String toCardDateFormat(String date) {
try {
Date value = CARD_DATE_FORMAT.parse(date);
SimpleDateFormat dateFormatter = new SimpleDateFormat("yy-MM", Locale.getDefault());
String datetimeLocale = dateFormatter.format(value);
String newDate = datetimeLocale + "-01";
return newDate;
} catch (ParseException e) {
return null;
}
}
for date object you can use this:
public static Date toCardDateFormat(String date) {
try {
Date value = CARD_DATE_FORMAT.parse(date);
SimpleDateFormat dateFormatter = new SimpleDateFormat("yy-MM", Locale.getDefault());
String datetimeLocale = dateFormatter.format(value);
String newDate = datetimeLocale + "-01";
SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd",Locale.getDefault());
Date d = dateFormat.parse(newDate);
return d;
} catch (ParseException e) {
return null;
}
}
Maciej's answer is correct, but if you use Java 8 or higher, it's better to use the java.time classes:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMdd");
// parse and change the day of month
LocalDate d = LocalDate.parse("200908", formatter).withDayOfMonth(1);
System.out.println(d); // 2020-09-01
Note that the LocalDate is printed in the format you want - which is ISO8601 compliant. If you want a different format, just use another DateTimeFormatter and call the format method.
Manually changing the string, as suggested by others, might also work, but if you're dealing with dates, why not use a proper date-handling API? Direct string manipulation won't help you in cases like invalid dates (the formatter will throw an exception for invalid inputs), or if you try to change the day to invalid values (such as day 31 for April, or 29 for February in a non-leap year, which are checked by the API and throw an exception if the value is invalid).
Your code has multi threading issue, best create locally in your convert function to avoid it (otherwise you will have troubles with multiple thread as this class is not thread-safe)
Answer to your question is (using old Date api) - you can use Calendar to do it:
public static Date toCardDateFormat(String date){
Date result = null;
try {
result = new SimpleDateFormat("yyMMdd", Locale.getDefault()).parse(date);
} catch (ParseException e) {
return null; // or better throw exception or return Optional.empty()
}
Calendar cal = Calendar.getInstance();
cal.setTime(result);
cal.set(Calendar.DAY_OF_MONTH, 1);
return cal.getTime();
}
you could try something like this:
String[] arr = date.split("-");
String newDate = arr[0] + "-" + arr[1] + "-01";
private static final DateTimeFormatter CARD_DATE_FORMAT
= DateTimeFormatter.ofPattern("yyMMdd", Locale.getDefault());
public static Optional<YearMonth> toCardDateFormat(String date) {
try {
return Optional.of(YearMonth.parse(date, CARD_DATE_FORMAT));
} catch (DateTimeParseException e) {
return Optional.empty();
}
}
Don’t return null from a method. The risk of a NullPointerException on the caller’s side would be great. If you believe that not returning a value is the right thing in case of a string in the wrong format or containing an invalid date, use Optional to force the caller to take the possibility of no return value into account. Another obvious option is to leave any parsing exception to the caller:
public static YearMonth toCardDateFormat(String date) {
return YearMonth.parse(date, CARD_DATE_FORMAT);
}
DateTimeParseException is an unchecked exception, so needs not be declared in the method signature. Let’s try it:
System.out.println(toCardDateFormat("200908"));
This prints:
2020-09
Other messages:
I am using and warmly recommending java.time, the modern Java date and time API. The old date-time classes from Java 1.0 and 1.1 are now long outdated, and SimpleDateFormat in particular is notoriously troublesome. I think you should avoid them. The modern API is so much nicer to work with.
It seems you would really prefer to remove the day of month so you only have the month and year? The YearMonth class from java.time does exactly that for you. If instead you wanted a full date, use the LocalDate class as in xunts’ answer.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Experts,
I would like to get current datetime in a given timezone for global usage.
So,
I create a class like below, but it shows syntax error for the df.setTimeZone statement. What is the neat way to achieve this? More specific, I would like to set timezone property for a class member rather than a local variable.
I defined many date format through SimpleDateFormat, how to specify a timezone for all of them? (.setTimeZone seems only for one date format) Thanks.
public class Global {
static SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setTimeZone(TimeZone.getTimeZone("GIVEN_TIMEZONE"));
static String strDate = df.format(new Date());
}
If you absolutely must do it with static fields, you need the code to be in a static initializer block:
class Global {
static SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
static {
df.setTimeZone(TimeZone.getTimeZone("GIVEN_TIMEZONE"));
}
static String strDate = df.format(new Date());
}
UPDATE
If you have lot of dates to do like that, with different date formats and/or time zones, it may be better to use a helper method.
class Global {
static String strDate = format(new Date(), "dd/MM/yyyy", "GIVEN_TIMEZONE");
private static String format(Date date, String format, String timeZoneID) {
SimpleDateFormat df = new SimpleDateFormat(format);
df.setTimeZone(TimeZone.getTimeZone(timeZoneID));
return df.format(date);
}
}
Please try in below possible syntax:
String dtc = "2014-04-02T07:59:02.111Z";
SimpleDateFormat readDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
readDate.setTimeZone(TimeZone.getTimeZone("GMT")); // Important line
Date date = readDate.parse(dtc);
SimpleDateFormat writeDate = new SimpleDateFormat("dd.MM.yyyy, HH.mm");
writeDate.setTimeZone(TimeZone.getTimeZone("GMT+04:00")); // Important line
String s = writeDate.format(date);
You need to import below class:
https://developer.android.com/reference/java/util/TimeZone.html
This question already has answers here:
how to get a list of dates between two dates in java
(23 answers)
Closed 6 years ago.
I'm trying to get an array of Dates, while my input is a 'from'/'to' structure.
So my input is:
String date1 = "2014-01-01";
String date2 = "2014-05-01";
My output should be an Arraylist with all dates between date1 and date2.
I've already looked for this, but I could only find questions about the difference between 2 dates:
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
try {
Date date1 = myFormat.parse(inputString1);
Date date2 = myFormat.parse(inputString2);
long diff = date2.getTime() - date1.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff,TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}
Any hints or suggestions? All other questions are for iOS or SQL.
Take a look at JodaTime: http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html
DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);
List<Date> allDates = new ArrayList();
while( dateTime1.before(dateTime2) ){
allDates.add( dateTime1.toDate() );
dateTime1 = dateTime1.plusDays(1);
}
Below is the code to get array of dates between the two string date.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
public class DateFormatExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String date1 = "2014-01-01";
String date2 = "2014-05-01";
try {
Date d1 = myFormat.parse(date1);
Date d2 = myFormat.parse(date2);
List<Date> allDates = new ArrayList<Date>();
List<String> allDatesString = new ArrayList<String>();
while( d1.before(d2) ){
d1 = addDays(d1, 1);
allDates.add(d1);
allDatesString.add(formatter.format(d1));
}
System.out.println(allDates);
System.out.println(allDatesString);
} catch (ParseException e) {
e.printStackTrace();
}
}
private static Date addDays(Date d1, int i) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d1);
cal.add(Calendar.DATE, 1);
return cal.getTime();
}
}
If you don't want to use third party libraries you can use Calendar:
Check here a working demo.
public static void main(String[] args) throws Exception {
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
ArrayList<Date> dates = new ArrayList<Date>();
try {
Date date1 = myFormat.parse(inputString1);
Calendar c1 = DateToCalendar(date1);
Date date2 = myFormat.parse(inputString2);
Calendar c2 = DateToCalendar(date2);
while (!areEqualDate(c1, c2)) {
dates.add(c1.getTime());
System.out.println (c1.getTime());
c1.add(Calendar.DAY_OF_YEAR, 1);
}
} catch (ParseException e) {
e.printStackTrace();
}
// ArrayList<Date> dates >> contain all dates between both given days.
}
private static boolean areEqualDate(Calendar c1, Calendar c2) {
if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) return false;
if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) return false;
if (c1.get(Calendar.DAY_OF_YEAR) != c2.get(Calendar.DAY_OF_YEAR)) return false;
return true;
}
public static Calendar DateToCalendar(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
I like JodaTime, but this can also be done without 3rd party libraries by using java.util.Calendar. Given a Calendar object, one can use its add method to increase certain fields of the date while honoring the calendar rules (like adding 1 day to the 31st of January gets you to the 1st of February, not to the 32nd of January).
First get the dates into one Calendar object each, in the correct chronological order so adding is going in the right direction later:
Calendar cStart = Calendar.getInstance(),
cStop = Calendar.getInstance();
if (date1.before(date2)) {
cStart.setTime(date1);
cStop.setTime(date2);
} else {
cStart.setTime(date2);
cStop.setTime(date1);
date1 and date2 are the parsed Date objects from your question, for simplicity's sake.
Next, loop over an "add 1 to day-of-year" instruction until this gets you beyond the stop date:
do {
System.out.println(pretty(cStart));
cStart.add(Calendar.DAY_OF_YEAR, 1);
} while (cStart.before(cStop));
And lastly print the stop date
System.out.println(pretty(cStop));
pretty() is just some mini method sending the calendar through a SDF, like the one you used for parsing the Strings in the first place.
This solution will print the date range, including the start and stop dates, and might need some tweaking around the edge cases (like date1==date2). Can be easily adapted to exclude the start and stop dates. Printing can be swapped for aggregation of course. To get a Date object from the calendar, use the getTime() method (returns a snapshot, not a live reference).
The documentation for the relevant (Gregorian)Calendar can be found here.
In case you are using Guava, there is a very elegant solution to this problem.
Guava has two neat classes, such as Range and ContiguousSet, which implement exactly what you need: first one operates on ranges of values, and second one - is able to convert a range to a set of discrete values.
Example of usage of both (together with JodaTime):
LocalDate start = LocalDate.parse("2015-01-01");
LocalDate end = LocalDate.parse("2019-02-01");
Range<LocalDate> range = Range.closed(start, end); //Creates a "closed" range, that is both dates are inclusive. There are also options like "openClosed", "closedOpen" and "open"
final Set<LocalDate> daySet = ContiguousSet.create(range, LocalDateDomain.INSTANCE); //Create a "virtual" set of days in given the range. "virtual" part means that if you create a set of 10 thousand years, it will not eat your memory at all
for (LocalDate day : daySet) {
//...operation...
}
Personally, I really prefer this way, as it eliminates some problems with understanding closed/open ranges, and makes code much easier to read and understand, while making no impact on performance. Also, it works with any kinds of dates, any libraries (you can swap YodaTime to Java8 Dates or even Java7- Date-based implementation).
Moreover, it allows you to do some neat operations on ranges like intersections, unions, spanning of ranges, incredibly fast "contains" and so on.
Only downsides are:
Dependence on Guava.
Need to create a special "DiscreteDomain" class, which Guava uses to understand where one date ends and other begins.
Example of LocalDateDomain implementation which operates as a bridge between Guava and JodaTime:
public class LocalDateDomain extends DiscreteDomain<LocalDate> {
public static final LocalDateDomain INSTANCE = new LocalDateDomain();
#Override
public LocalDate next(LocalDate value) {
return value.plusDays(1);
}
#Override
public LocalDate previous(LocalDate value) {
return value.minusDays(1);
}
#Override
public long distance(LocalDate start, LocalDate end) {
return Days.daysBetween(start, end).getDays();
}
}
I already know that OP isn't using Java 8 but here's the current solution - Java has been revamped and the new java.time API does every conceivable job in that regard:
//change these values :
LocalDate ld1 = LocalDate.ofEpochDay(0);
LocalDate ld2 = LocalDate.now();
//do NOT change these:
final LocalDate begin = ld1.isBefore(ld2) ? ld1 : ld2;
final LocalDate end = ld2.isAfter(ld1) ? ld2 : ld1;
for (int i = 0; i < begin.until(end, ChronoUnit.DAYS); i++) {
final LocalDate curDate = begin.plusDays(i);
System.out.println("current date : " + curDate);
}
This will output every valid day between the two dates whereas most of the other solutions will also give you invalid ones; heres the thing: temporal calculations need to be done on timezone-independent data - the output on the other hand may very well be timezone and/or chronology -dependent.
Thats why there are packages like java.time.format - simply calculate your time/date values and format them for your chosen region ... thats how its done correctly.
If you need to convert temporal input there are also useful functions in the time-API, i recommend doing a thorough tutorial on the subject, a few good introductions may be this and especially that :
There are two basic ways to represent time. One way represents time in
human terms, referred to as human time, such as year, month, day,
hour, minute and second. The other way, machine time, measures time
continuously along a timeline from an origin, called the epoch, in
nanosecond resolution. The Date-Time package provides a rich array of
classes for representing date and time. Some classes in the Date-Time
API are intended to represent machine time, and others are more suited
to representing human time.
I have a string containing a date in the format YYYY-MM-DD.
How would you suggest I go about converting it to the format DD-MM-YYYY in the best possible way?
This is how I would do it naively:
import java.util.*;
public class test {
public static void main(String[] args) {
String date = (String) args[0];
System.out.println(date); //outputs: YYYY-MM-DD
System.out.println(doConvert(date)); //outputs: DD-MM-YYYY
}
public static String doConvert(String d) {
String dateRev = "";
String[] dateArr = d.split("-");
for(int i=dateArr.length-1 ; i>=0 ; i--) {
if(i!=dateArr.length-1)
dateRev += "-";
dateRev += dateArr[i];
}
return dateRev;
}
}
But are there any other, more elegant AND effective way of doing it? Ie. using some built-in feature? I have not been able to find one, while quickly searching the API.
Anyone here know an alternative way?
Use java.util.DateFormat:
DateFormat fromFormat = new SimpleDateFormat("yyyy-MM-dd");
fromFormat.setLenient(false);
DateFormat toFormat = new SimpleDateFormat("dd-MM-yyyy");
toFormat.setLenient(false);
String dateStr = "2011-07-09";
Date date = fromFormat.parse(dateStr);
System.out.println(toFormat.format(date));
Here’s the modern answer.
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
public static String doConvert(String d) {
return LocalDate.parse(d).format(formatter);
}
With this we may do for example:
System.out.println(doConvert("2017-06-30"));
This prints
30-06-2017
I am exploiting the fact that the format you have, YYYY-MM-DD, conforms with the ISO 8601 standard, a standard that the modern Java date and time classes “understand” natively, so we need no explicit formatter for parsing, only one for formatting.
When this question was asked in 2011, SimpleDateFormat was also the answer I would have given. The newer date and time API came out with Java 8 early in 2014 and has also been backported to Java 6 and 7 in the ThreeTen-Backport project. For Android, see the ThreeTenABP project. So these days honestly I see no excuse for still using SimpleDateFormat and Date. The newer classes are much more programmer friendly and nice to work with.
Best to use a SimpleDateFormat (API) object to convert the String to a Date object. You can then convert via another SimpleDateFormat object to whatever String representation you wish giving you tremendous flexibility.
If you're not looking for String to Date conversion and vice-versa, and thus don't need to handle invalid dates or anything, String manipulation is the easiest and most efficient way. But i's much less readable and maintainable than using DateFormat.
String dateInNewFormat = dateInOldFormat.substring(8)
+ dateInOldFormat.substring(4, 8)
+ dateInOldFormat.substring(0, 4)
import java.util.DateFormat;
// Convert String Date To Another String Date
public String convertStringDateToAnotherStringDate(String stringdate, String stringdateformat, String returndateformat){
try {
Date date = new SimpleDateFormat(stringdateformat).parse(stringdate);
String returndate = new SimpleDateFormat(returndateformat).format(date);
return returndate;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
//-------
String resultDate = convertStringDateToAnotherStringDate("1997-01-20", "yyyy-MM-dd", "MM/dd/yyyy")
System.out.println(resultDate);
Result (date string) : 01/20/1997