Using calendars or Joda-Time in java - java

I have a document that starts on date X and end on date Y and and goes up by one day. My task is to go through this document and find out how many days are missing from the document.
Example:
19990904 56.00
19990905 57.00
19990907 60.00
Need to print out that 19900906 is missing.
I have done some research and read about java calendar, Date, and Joda-Time, yet was unable to understand what any of them are. Can some one please explain what these functions I just mentioned do, and then make a suggestion on how to use one to accomplish my goal?
I already have this code:
String name = getFileName();
BufferedReader reader = new BufferedReader(new FileReader(name));
String line;
while ((line = reader.readLine()) != null)
{ //while
String delims = "[ ]+";
String [] holder = line.split(delims);
// System.out.println("*");
int date = Integer.parseInt(holder[0]);
//System.out.println(holder[0]);
double price = Double.parseDouble(holder[1]);

With JodaTime. (If you are only concerned with date, you should NOT use datetimes, or mess with hours,minutes, dst issues.)
final DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMdd");
LocalDate date=null;
while( (line = getNextLine())!=null) {
String dateAsString = line.split(delims)[0];
LocalDate founddate = dtf.parseLocalDate(dateAsString);
if(date==null) { date= founddate; continue;} // first
if(founddate.before(date)) throw new RuntimeException("date not sorted?");
if(founddate.equals(date)) continue; // dup dates are ok?
date = date.plusDays(1);
while(date.before(foundate)){
System.out.println("Date not found: " +date);
date = date.plusDays(1);
}
}
If you only need to count missing days:
LocalDate date=null;
int cont=0;
while( (line = getNextLine())!=null) {
String dateAsString = line.split(delims)[0];
LocalDate founddate = dtf.parseLocalDate(dateAsString);
if(date==null) { date= founddate; continue;} // first
if(founddate.before(date)) throw new RuntimeException("date not sorted?");
if(founddate.equals(date)) continue; // dup dates are ok?
cont += Days.daysBetween(date, founddate)-1;
date = founddate;
}

LocalDate x = new LocalDate(dateX);
LocalDate y = new LocalDate(dateY);
int i = Days.daysBetween(x, y).getDays();
missingdays = originalSizeofList - i;
This is joda-time, its much easier than vanilla java.

Related

Java String to date parsing error, how to do it properly

I am interested to know if my code is correct and it doesn't have any issues. Date is taken from binary file, written as a string in such format YYYY-MM-DD/Hours-minutes-seconds example: 2022-01-23/12:00:00.
Program was meant to check date if it's expiring or expired, add it to proper list and display it after loops end.
public static void expiration_date(String filepath){
try {
DataInputStream read = new DataInputStream(new FileInputStream(filepath));
DateTimeFormatter format_day = DateTimeFormatter.ofPattern("uuuu/MM/dd");
DateTimeFormatter format_hour = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalDate now_day = LocalDate.now();
LocalDateTime now_hour = LocalDateTime.now();
ArrayList<String> dates = new ArrayList<>();
ArrayList<String> expire_in_week = new ArrayList<>();
ArrayList<String> expire_tomorrow = new ArrayList<>();
ArrayList<String> expire_today = new ArrayList<>();
ArrayList<String> expired = new ArrayList<>();
while(read.available()>0) {
String name = read.readUTF();
String surname = read.readUTF();
String date = read.readUTF();
String cardcode = read.readUTF();
String cardtype = read.readUTF();
int contract_num = read.readInt();
String cert_num = read.readUTF();
String phone_num = read.readUTF();
String email = read.readUTF();
String status = read.readUTF();
String comment = read.readUTF();
dates.add(date);
for (String s:dates){
String[] data = s.split("/");
String days =data[0];
LocalDate date_days = LocalDate.parse(days.replace("-", "/"), format_day);
String hours =data[1];
LocalTime date_hours = LocalTime.parse(hours.replace("-", ":"),format_hour);
long daysbetween = ChronoUnit.DAYS.between(now_day,date_days);
long hoursbetween = ChronoUnit.HOURS.between(now_hour,date_hours);
if (daysbetween==7){
expire_in_week.add(cert_num);
}else if (daysbetween==1){
expire_tomorrow.add(cert_num);
}else if (daysbetween==0 && hoursbetween>0){
expire_today.add(cert_num);
}else if (daysbetween<0 || (daysbetween==0 && hoursbetween<0)){
expired.add(cert_num);
}else{}
}
}
System.out.println("Certificates that expires:");
System.out.println("Next week");
for (String w:expire_in_week){
System.out.print(w+"|");
}
System.out.println("Tomorrow");
for (String tm:expire_tomorrow){
System.out.print(tm+"|");
}
System.out.println("Today");
for (String td:expire_today){
System.out.print(td+"|");
}
System.out.println("Today");
for (String ex:expired){
System.out.print(ex+"|");
}
}catch(FileNotFoundException ex){ex.printStackTrace();}
catch(IOException ex){ex.printStackTrace();}
}
When i start it i got error message returned:
Exception in thread "main" java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 12:00 of type java.time.LocalTime
at java.base/java.time.LocalDateTime.from(LocalDateTime.java:463)
at java.base/java.time.LocalDateTime.until(LocalDateTime.java:1677)
at java.base/java.time.temporal.ChronoUnit.between(ChronoUnit.java:272)
at com.company.program.expiration_date(program.java:189)
at com.company.program.main(program.java:364)
Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: 12:00 of type java.time.LocalTime
at java.base/java.time.LocalDate.from(LocalDate.java:398)
at java.base/java.time.LocalDateTime.from(LocalDateTime.java:458)
... 4 more
The issue is because date_hours is of type LocalDateTime and date_hours is of type LocalTime. Try using the same type for both.
LocalTime now_hour = LocalTime.now();
Side note to parse the values of LocalDate and LocalTime you can try this
String data = "2022-01-23/12-00-00";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd/HH-mm-ss");
LocalDate dateDays = LocalDate.parse(data, dateTimeFormatter);
LocalTime dateHours = LocalTime.parse(data, dateTimeFormatter);
See working example of your code here: https://github.com/RobbingDaHood/answers/blob/master/so70824574/src/Main.java
You LocalTime date_hours needs a timezone before it can be compared with LocalDateTime now_hour. So either add one to date_hours as I did in the code or remove the one from now_hour.
In my code the date_hours would get the system timezone, as the code is now. Be aware that maybe your file is not using that timezone.
Output of the example code is:
Certificates that expires:
Next week
Tomorrow
Today
Today
Cert1|
You can read more here
https://www.baeldung.com/java-8-date-time-intro
That will give you a good intro to the different date types in Java.

Parse a date from a string

I have String like this:
String strDateTimeStamp = "2016-02-29 18:31:51";
Now I would like to extract it to get result in a below format:
String strYear = "2016";
String strMonth = "02";
String strDate = "29";
String strHour = "18";
String strMinute = "31";
String strSecond = "51";
If you are working with dates you should consider using Calendar :
String strDateTimeStamp = "2016-02-29 18:31:51";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse(strDateTimeStamp);
Calendar cal = new Calendar.Builder().setInstant(date).build();
String strYear = Integer.toString(cal.get(Calendar.YEAR));
// Calendar MONTH is starting from 0 we need to add 1
String strMonth = Integer.toString(cal.get(Calendar.MONTH) + 1);
String strDate = Integer.toString(cal.get(Calendar.DATE));
String strHour = Integer.toString(cal.get(Calendar.HOUR_OF_DAY));
String strMinute = Integer.toString(cal.get(Calendar.MINUTE));
String strSecond = Integer.toString(cal.get(Calendar.SECOND));
All of the Answers using java.util.Date and java.text.DateFormat/.SimpleDateFormat are outmoded. Those old date-time classes are poorly designed, confusing, and troublesome. Avoid them.
java.time
The java.time framework is built into Java 8 and later. A vast improvement over the old date-time classes.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
First, replace the SPACE in the middle of your input string with a T to conform with the ISO 8601 standard. These standard formats are used by default in the java.time classes when parsing/generating strings.
String input = "2016-02-29 18:31:51".replace( " " , "T" );
Parse as a LocalDateTime. The “Local” means not associated with any time zone. So this is not an actual moment on the timeline. But apparently not an issue in the context of this Question.
LocalDateTime ldt = LocalDateTime.parse( input );
Now you can ask for your various pieces as needed by calling the various getter methods. These methods return an int primitive which you can, of course, convert to String values.
getYear
getMonthValue (or getMonth for Month enum))
getDayOfMonth (and getDayOfWeek for DayOfWeek enum)
getHour
getMinute
getSecond
getNano (the fraction of a second)
Try This..
String CurrentString = "2016-02-29 18:31:51";
String[] separated = CurrentString.split(" ");
String date = separated[0];
String time = separated[1];
String[] separated_date = date.split("-");
String[] separated_time = time.split(":");
String strYear = separated_date[0];
String strMonth = separated_date[1];
String strDate = separated_date[2];
String strHour = separated_time[0];
String strMinute = separated_time[1];
String strSecond = separated_time[2];
You can do like this by splitting your String
String[] splittedString = strDateTimeStamp.split("-|:|\\s");
String strYear = splittedString[0];
String strMonth = splittedString[1];
String strDate = splittedString[2];
String strHour = splittedString[3];
String strMinute = splittedString[4];
String strSecond = splittedString[5];
First split string using split(" ") on the basis of space ..it will give you a array of string of length 2 . which contains (2016-03-04) and (16:32:33) . Then split both string againg using split("-") and split(":") reapectively . you will get your answer. Please try code at your own may better to you.
I suggest to use regex with a pattern like "[- :]"
Example:
public static void main(String[] args) {
String strDateTimeStamp = "2016-02-29 18:31:51";
String[] solution = strDateTimeStamp.split("[- :]");
for (int i = 0; i < solution.length; i++) {
System.out.println(solution[i]);
}
}
this will generate an array with all the elements you need
String strDateTimeStamp = "2016-02-29 18:31:51";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse(strDateTimeStamp);
Calendar cal = new Calendar.Builder().setInstant(date).build();
String strYear = Integer.toString(cal.get(Calendar.YEAR));
// Calendar MONTH is starting from 0 we need to add 1
String strMonth = Integer.toString(cal.get(Calendar.MONTH) + 1);
String strDate = Integer.toString(cal.get(Calendar.DATE));
String strHour = Integer.toString(cal.get(Calendar.HOUR_OF_DAY));
String strMinute = Integer.toString(cal.get(Calendar.MINUTE));
String strSecond = Integer.toString(cal.get(Calendar.SECOND));

How to get month and day from given string? [duplicate]

This question already has answers here:
Java string to date conversion
(17 answers)
Closed 8 years ago.
How can I get day and date from given Strings. For example:
String date="25-12-2014";
How to get date and day from given string?
Expected output is,
25
Thu
I got stuck when I tried this.
private static String getFormatedDate(String strDate) {
String result = "";
if(strDate != null) {
if (strDate.contains("-")) {
String[] dates = strDate.split("-");
for(int i=0;i<dates.length;i++) {
result = result + Utils.replaceDateFormat(dates[i].trim(),"MMM dd", "EE, M.dd") + ("-");
}
int lastIndex = result.lastIndexOf("-");
result = result.substring(0, lastIndex).trim();
}
else {
result = Utils.replaceDateFormat(strDate.trim(),"MMM dd", "EE, M.dd");
}
}
return result;
}
Utils:
public static String replaceDateFormat(String value, String actualFormat, String exceptedFormat) {
final int currentYear = Calendar.getInstance().get(Calendar.YEAR);
final SimpleDateFormat fromDate = new SimpleDateFormat(actualFormat);
final SimpleDateFormat toDate = new SimpleDateFormat(exceptedFormat);
Date convertedFromDate = null;
try {
convertedFromDate = fromDate.parse(value);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
final Calendar c1 = Calendar.getInstance();
c1.setTime(convertedFromDate);
c1.set(Calendar.YEAR, currentYear);
return toDate.format(c1.getTime());
}
Your methods are very convoluted for a relatively simple task. Why don't you use SimpleDateFormat? You can use the parse method. For example:
Date date = new SimpleDateFormat("dd-MM-yyyy").parse(string);
And then you can get the required fields from there.
EDIT
To get the day of the week, you were right with this code:
Date d = date.parse(result);
Calendar c = Calendar.getInstance();
c.setTime(d);
int day=c.get(Calendar.DAY_OF_WEEK);
And then if you want it in the format above, you could just make an array filled with the days of the week:
String[] daysOfWeek = new String[]{"Sun","Mon"... etc}
String day = daysOfWeek[day - 1];
You can use the method from Calendar:
String date = "25-12-2014";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(format.parse(date));
int day = cal.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
DateFormatSymbols symbols = new DateFormatSymbols(new Locale("en"));
String[] days = symbols.getShortWeekdays();
System.out.printf("%02d %3s\n", day, days[dayOfWeek]);
The symbols can be set to your Locale zone.
if you are allowed to use java 8 you can give LocalDate a chance:
String date = "25-12-2014";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate ld = LocalDate.parse(date, formatter);
System.out.println(ld.getDayOfMonth() + ", " + ld.getDayOfWeek());
Output is:
25, THURSDAY
EDIT:
System.out.println(ld.getDayOfMonth() + ", " + ld.getDayOfWeek().substring(0, 3));
#No aNoNym suggestion is right, with the following you get
25, THU

Random Number Change With Joda Time

My Joda Time is changing a number from 9 to 1 in my code.
Code:
String name = getFileName();
BufferedReader reader = new BufferedReader(new FileReader(name));
DateTime firstDate = new DateTime();
DateTimeFormatter dtf = DateTimeFormat.forPattern("YYYYMMDD");
String date = dtf.print(firstDate);
System.out.println(date);
String fake;
while ((fake = reader.readLine()) != null) {
String [] holder = fake.split(" ");
firstDate = dtf.parseDateTime(holder[2]);
System.out.println(holder[2]);
System.out.println(firstDate);
String useFirstDate = dtf.print(firstDate);
System.out.println(useFirstDate);
System.out.println("here");
break;
}
Output:
Please input File Name
futuresmin
201306172 //System.out.println(date);
19870901 //System.out.println(holder[2]);
1987-01-01T00:00:00.000-05:00 //System.out.println(firstDate);
19870101 //System.out.println(useFirstDate);
here //System.out.println("here");
I do not know if this is a common issue, or if it is just me, yet I have not found anything on the internet regarding this issue. Why would Joda Time change 19870901 to 19870101?
"DD" is day of year, not day of month, which is "dd". Your format string is incorrect.
On an unrelated note, it's difficult to correlate your output with your code. In general, it's best to keep the noise to a minimum, and make it explicit which output line comes from which code, like with a header.

How to get the day of month from a formatted string?

When I create a Date from parsing a String and access the day of the month, I get the wrong value.
Date datearr = null;
DateFormat df1 = new SimpleDateFormat("dd-MM-yyyy");
String dataa = "17-03-2012";
try {
datearr = df1.parse(dataa);
} catch (ParseException e) {
Toast.makeText(this, "err", 1000).show();
}
int DPDMonth = datearr.getMonth() + 1;
int DPDDay = datearr.getDay();
int DPDYear = datearr.getYear() + 1900;
System.out.println(Integer.toString(DPDDay)+"-"+Integer.toString(DPDMonth)+"-"+Integer.toString(DPDYear));
Why do I get 0 instead of 17?
03-11 10:24:44.286: I/System.out(2978): 0-3-2012
Here's a snippet the doesn't use deprecated methods anymore, fixes naming issues and simplifies the output.
Date datearr = null;
DateFormat df1 = new SimpleDateFormat("dd-MM-yyyy");
String dataa = "17-03-2012";
try {
datearr = df1.parse(dataa);
} catch (ParseException e) {
Toast.makeText(this, "err", 1000).show();
return; // do not continue in case of a parse problem!!
}
// "convert" the Date instance to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(datearr);
// use the Calendar the get the fields
int dPDMonth = cal.get(Calendar.MONTH)+1;
int dPDDay = cal.get(Calendar.DAY_OF_MONTH);
int dPDYear = cal.get(Calendar.YEAR);
// simplified output - no need to create strings
System.out.println(dPDDay+"-"+dPDMonth+"-"+dPDYear);
You should use
int DPDDay = datearr.getDate();
getDay() return a day in week
This kind of work is much easier when using the third-party library, Joda-Time 2.3.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
String dateString = "17-03-2012";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );
DateTime dateTime = formatter.parseDateTime( dateString ).withTimeAtStartOfDay();
int dayOfMonth = dateTime.getDayOfMonth();

Categories