I have a String Array which is contain dates that read from a CSV file.
Now I want to count how many weekend days are in that array. But in my array there are some dates are duplicated. Here shows part of the data that is containing in my Array.
12/2/2010
12/3/2010
12/5/2010
12/10/2010
12/5/2010
12/13/2010
12/14/2010
12/12/2010
In this data set 12/5/2010 is Sunday (but there are two records) & 12/12/2010 is Saturday (has One record). In output, I want to print number of weekend days in this array using java. Compared to this example the Answer should be 2.
FileInputStream fis=new FileInputStream("c:/cdr2.csv");
InputStreamReader isr=new InputStreamReader(fis);
BufferedReader bf = new BufferedReader(isr);
while (bf.ready()) {
String line = bf.readLine();
String[] values=line.split(",");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/d/yyyy");
Date date = simpleDateFormat.parse(values[2]);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
}
First, you need to write a method that determines if a given Date is a weekend or not:
public static boolean isWeekend(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
return dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY;
}
Then, you need to define a DateFormat, so that you can parse a date String into a java.util.Date. Finally, you can use a Set to assure every weekend you find is not going to be duplicated:
public static void main(String[] args) throws ParseException {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
String[] dates = { "12/2/2010", "12/3/2010", "12/5/2010", "12/10/2010", "12/5/2010", "12/13/2010", "12/14/2010", "12/12/2010" };
Set<String> weekends = new HashSet<String>();
for (String dt : dates) {
Date date = dateFormat.parse(dt);
if (isWeekend(date)) {
weekends.add(dt);
}
}
System.out.println("There are " + weekends.size() + " distinct weekends."); // 2
}
I would say you need to first remove duplicates and then check which of them are weekend days:
Set<String> set = new HashSet<String>( Arrays.asList(yourArrayOfDateStrings) );
DateFormat df = new SimpleDateFormat(yourDatePattern);
Calendar calendar = Calendar.getInstance();
int weekendDays = 0;
for (String dateString : set) {
calendar.setTime( df.parse(dateString) );
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) {
weekendDays++;
}
}
I don't use java date, ever!
I agree with Costi Ciudatu, use a Set to remove duplicates.
:) please to send you teh codez using JodaTime
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeField;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
public class Dates
{
static String[] localTestDate = new String[] {"12/2/2010", "12/3/2010", "12/5/2010", "12/10/2010", "12/5/2010", "12/13/2010", "12/14/2010", "12/12/2010"};
static DateTimeFormatter dateFactory = DateTimeFormat.forPattern("MM/d/yyyy");
public static void main(String[] args)
{
// final Set<DateTime> uniqueDates = generateUniqueDates(localTestDate);
final Set<DateTime> uniqueDates = generateUniqueDates(readCommonSeparatedFile(args[0]));
int numberOfWeekendDates = 0;
for(DateTime date : uniqueDates)
{
if(isWeekend(date)) numberOfWeekendDates++;
}
System.out.println("There are " + numberOfWeekendDates + " weekend days in your list.");
}
private static boolean isWeekend(DateTime dateTime)
{
return (DateTimeConstants.SATURDAY == dateTime.dayOfWeek().get() || DateTimeConstants.SUNDAY == dateTime.dayOfWeek().get());
}
private static String[] readCommonSeparatedFile(final String fileName)
{
FileInputStream fileInputStream = null;
String[] result = null;
try
{
fileInputStream = new FileInputStream(fileName);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
while (bufferedReader.ready())
{
String line = bufferedReader.readLine();
result = line.split(",");
}
}
catch (IOException e)
{
//log error some where
throw new RuntimeException("aw, snap!");
}
return result;
}
private static Set<DateTime> generateUniqueDates(final String[] dates)
{
final Set<DateTime> dateTimes = new HashSet<DateTime>();
for (String date : dates)
{
dateTimes.add(dateFactory.parseDateTime(date).toDateTime());
}
return dateTimes;
}
}
Related
This question already has answers here:
How to compare dates in Java? [duplicate]
(11 answers)
Closed 5 years ago.
I'm trying to write 'isPast(String dateStr)' function, which receives date string and returns true if it's in the past and false otherwise.
private static boolean isPast(String dateStr) {
Calendar c = GregorianCalendar.getInstance();
int currentYear = c.get(Calendar.YEAR);
int currentMonth = c.get(Calendar.MONTH);
int currentDay = c.get(Calendar.DAY_OF_MONTH);
int currentHour = c.get(Calendar.HOUR_OF_DAY);
int currentMinute = c.get(Calendar.MINUTE);
c.set(currentYear, currentMonth, currentDay, currentHour, currentMinute);
Date now = c.getTime();
SimpleDateFormat sdfDates = new SimpleDateFormat("dd/m/yyyy");
Date date = null;
try {
date = sdfDates.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
if (now.compareTo(date) == 1){
System.out.println(dateStr + " date given is past");
return true;
}
System.out.println(dateStr + " date given is future");
return false;
}
And i'm calling it with:
String str1 = "22/04/2018";
String str2 = "22/01/2018";
System.out.println(isPast(str1));
System.out.println(isPast(str2));
And the output is:
22/04/2018 date given is past
22/01/2018 date given is past
What is going on here? It's not true. I'm on this for too long - it should be simple, obviously i'm missing something with that Calendar object...
Use LocalDate that is available in Java 8
public static void main(String[] args) {
String str1 = "22/04/2018";
String str2 = "22/01/2018";
System.out.println(isPast(str1));
System.out.println(isPast(str2));
}
private static boolean isPast(String dateStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate dates = LocalDate.parse(dateStr, formatter);
return dates.isBefore(LocalDate.now());
}
Try this:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
private static final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
public static void main(String[] args) {
String str1 = "22/04/2018";
String str2 = "22/01/2018";
String str3 = "xx/01/2018";
Date now = new Date();
testDate (str1, now);
testDate (str2, now);
testDate (str3, now);
}
private static void testDate(String str, Date now) {
try {
if (sdf.parse(str).before(now)) {
System.out.println(str + " is in the past.");
} else {
System.out.println(str + " is in the future.");
}
} catch (ParseException e) {
System.out.println("Date not in format dd/MM/yyyy : " + str);
}
}
}
Output:
22/04/2018 is in the future.
22/01/2018 is in the past.
Date not in format dd/MM/yyyy : xx/01/2018
If you have to use Calendar, try this:
private static void testDateUsingCalendar (String str, Date now) {
try {
String[] split = str.split("/");
Calendar c = GregorianCalendar.getInstance();
c.set(Integer.valueOf(split[2]), Integer.valueOf(split[1]), Integer.valueOf(split[0]));
if (c.getTime().before(now)) {
System.out.println(str + " is in the past.");
} else {
System.out.println(str + " is in the future.");
}
} catch (Exception e) {
System.out.println("Date not in format dd/MM/yyyy : " + str);
}
}
This question already has answers here:
Adding n hours to a date in Java?
(16 answers)
Closed 7 years ago.
I have a TextView that store a getDate() value. This getDate() value is a date but the format is String
textview_device_datetime.setText(data.getDate().replace('T', ' '));
this is the result
16-08-2015 16:15:16
but i would add 2 hours to this String Date.
How can i do?
Any help is great.
Thanks
final String dateString = "16-08-2015 16:15:16";
final long millisToAdd = 7_200_000; //two hours
DateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Date d = format.parse(dateString);
d.setTime(d.getTime() + millisToAdd);
System.out.println("New value: " + d); //New value: Sun Aug 16 18:15:16 CEST 2015
Here I have attached the code for it with example.
import java.time.*;
import java.text.*;
import java.util.*;
public class AddTime
{
public static void main(String[] args)
{
String myTime = "16-08-2015 16:15:16";
System.out.println(addHour(myTime,2));
}
public static String addHour(String myTime,int number)
{
try
{
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Date d = df.parse(myTime);
Calendar cal = Calendar.getInstance();
cal.setTime(d);
cal.add(Calendar.HOUR, number);
String newTime = df.format(cal.getTime());
return newTime;
}
catch(ParseException e)
{
System.out.println(" Parsing Exception");
}
return null;
}
}
I need your help in getting the list of months and the years in String between two dates. The user will enter two dates in the String format of:
String date1 ="JAN-2015";
String date2 ="APR-2015";
So the result should be:
Jan-2015
FEB-2015
MAR-2015
I tried using the following code but it gave me wrong results:
List<Date> dates = new ArrayList<Date>();
String str_date ="JAN-2015";
String end_date ="APR-2015";
DateFormat formatter ;
formatter = new SimpleDateFormat("MMM-yyyy");
Date startDate = formatter.parse(str_date);
Date endDate = formatter.parse(end_date);
long endTime =endDate.getTime() ;
long curTime = startDate.getTime();
while (curTime <= endTime) {
dates.add(new Date(curTime));
curTime ++;
}
for(int i=0;i<dates.size();i++){
Date lDate =(Date)dates.get(i);
String ds = formatter.format(lDate);
System.out.println(ds);
}
Using the less code possible and basic java libraries and getting the result you asked for. So you can modify the date1 and date2 variables.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
String date1 = "JAN-2015";
String date2 = "APR-2015";
DateFormat formater = new SimpleDateFormat("MMM-yyyy");
Calendar beginCalendar = Calendar.getInstance();
Calendar finishCalendar = Calendar.getInstance();
try {
beginCalendar.setTime(formater.parse(date1));
finishCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
e.printStackTrace();
}
while (beginCalendar.before(finishCalendar)) {
// add one month to date per loop
String date = formater.format(beginCalendar.getTime()).toUpperCase();
System.out.println(date);
beginCalendar.add(Calendar.MONTH, 1);
}
}
}
In case your Java version is < 8 you could use Calendar as follows:
private final static DateFormat formatter = new SimpleDateFormat("MMM-yyyy", Locale.ENGLISH);
public static void main(String[] args) throws ParseException {
Calendar startDate = stringToCalendar("Jan-2015");
Calendar endDate = stringToCalendar("Apr-2015");
while (startDate.before(endDate)) {
System.out.println(formatter.format(startDate.getTime()));
startDate.add(Calendar.MONTH, 1);
}
}
private static Calendar stringToCalendar(String string) throws ParseException {
Date date = formatter.parse(string);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar;
}
If you have a luxury of Java 8 then the code becomes more simple:
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM-yyyy", Locale.ENGLISH);
YearMonth startDate = YearMonth.parse("Jan-2015", formatter);
YearMonth endDate = YearMonth.parse("Apr-2015", formatter);
while(startDate.isBefore(endDate)) {
System.out.println(startDate.format(formatter));
startDate = startDate.plusMonths(1);
}
}
My requirements:
ddmm + 2numbers
dd - day
mm - month
number - id number
Examples of my output
Today - 031201, 031202, 031203 ...
Tommorrow - 041201
Properties file: (idNumber.properties)
idNumber = 1;
Here is the java code I did:
public class Test{
public static void main(String[] args)
{
Test test = new Test();
test.generate();
}
public String generate()
{
DateFormat dateFormat = new SimpleDateFormat("ddMM");
Date date = new Date();
String currentDate = dateFormat.format(date);
String idNumber = generateIdNumber();
String complete = currentDate + idNumber;
return complete;
}
public String generateIdNumber(){
Properties idNoProp = new Properties();
InputStream idNoInput = new FileInputStream("idNumber.properties"); //java properties file
idNoProp.load(idNoInput);
String idNumber = idNoProp.getProperty("idNumber");
int idNo = Integer.valueOf(idNumber);
String result = "";
if (idNo < 10) {
result = "0" + idNo;
} else {
result = "" + idNo;
}
idNo++;
OutputStream output = new FileOutputStream("idNumber.properties");
idNoProp.setProperty("idNumber", "" + idNo);
idNoProp.store(output, null);
return result;
}
}
My question is how do I reset the tommorrow id number start from 01?
You can add a property LAST_VISIT to your properties file. When you want to save the properties file, set the current date to it. In this way
DateFormat dateFormat = new SimpleDateFormat("ddMM");
Date date = new Date();
String currentDate = dateFormat.format(date);
idNoProp.setProperty("LAST_VISIT", currentDate);
Now in generateIdNumber() first check the value of LAST_VISIT. If it dose not equal currentDate , you must reset idNo. It works for everyday and every tommorow.
Try to put a class static field to remember last used date for ids. Whenever you are in the next date relatively to the field you'll reset your idNo and update the last used date field (sorry for spelling)
You can store a Map<String,Integer> that would hold the last index for each String representation of date. This way, each date would have its own indices starting with 1.
You can run a scheduler which will reset the idNo at the start of each day, like at 00 hours. This will always gives you the consistent result, as if sometimes server/program restarts, it will not lead to any duplicate result.
if you want format a number with two number, example '01' you could do this:
String.format("%02d", Integer.valueOf(idNumber));
instead of:
int idNo = Integer.valueOf(idNumber);
String result = "";
if (idNo < 10) {
result = "0" + idNo;
} else {
result = "" + idNo;
}
public class Test{
public static void main(String[] args) throws IOException
{
Test test = new Test();
System.out.println(""+test.generate());
}
public String generate() throws IOException
{
DateFormat dateFormat = new SimpleDateFormat("ddMM");
Date date = new Date();
String currentDate = dateFormat.format(date);
String idNumber = generateIdNumber(currentDate);
String complete = currentDate + idNumber;
return complete;
}
public String generateIdNumber(String currentDate) throws IOException{
Properties idNoProp = new Properties();
InputStream idNoInput = new FileInputStream("idNumber.properties"); //java properties file
idNoProp.load(idNoInput);
String idNumber = idNoProp.getProperty("idNumber");
int idNo = Integer.valueOf(idNumber);
String strOnlyDay = currentDate.substring(0, 2);
System.out.println(strOnlyDay);// will return the first two characters of the day
String result = "";
if (idNo < 10) {
result = "0" + idNo;
} else {
result = "" + idNo;
}
idNo++;
OutputStream output = new FileOutputStream("idNumber.properties");
if (strOnlyDay.equals("01")){
idNo = 1;
}
idNoProp.setProperty("idNumber", "" + idNo);
idNoProp.store(output, null);
return result;
}
}
Try to pass the value of your current date into generateIdNumber than see the code. I hope this will help. Hoping you will preserve the value of idNo.
I have a class DurationFormatter as below:
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
public class DurationFormatter {
private final static PeriodFormatter DURATION_FORMATTER =
new PeriodFormatterBuilder().appendYears()
.appendSuffix("year", "years")
.appendSeparator(" ")
.appendMonths()
.appendSuffix("month", "months")
.appendSeparator(" ")
.appendDays()
.appendSuffix("day", "days")
.appendSeparator(" ")
.appendHours()
.appendSuffix("hour", "hours")
.appendSeparator(" ")
.appendMinutes()
.appendSuffix("minute", "minutes")
.appendSeparator(" ")
.appendSeconds()
.appendSuffix("second", "seconds")
.toFormatter();
public static String format(Date start) {
StringBuffer result = new StringBuffer();
DURATION_FORMATTER.printTo(result,
new Period(new DateTime(start), new DateTime()));
return result.toString();
}
public static String format(Date start, Date end) {
StringBuffer result = new StringBuffer();
DURATION_FORMATTER.printTo(result,
new Period(new DateTime(start),
end == null
? new DateTime()
: new DateTime(end)));
return result.toString();
}
}
And this is my Unit Test:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import junit.framework.Assert;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.junit.Test;
public class DurationFormatterTest {
#Test
public void testFormatDate() throws ParseException {
int years = 0;
int months = 0;
int weeks = 0;
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String dateString = "07/27/2010 12:07:34";
Date startDate = (Date) df.parse( dateString );
// Find duration 1
String duration1 = DurationFormatter.format(startDate);
// Parse duration 1 and set values into new Period
String[] tokens = duration1.split("[ ]");
for( int index = 0; index < tokens.length; index++ ) {
String token = tokens[index];
if( token.contains("years") ) {
years = Integer.valueOf(token.replace("years", ""));
System.out.println("Years are: " + years);
}
else if( token.contains("months") ) {
months = Integer.valueOf(token.replace("months", ""));
System.out.println("Months are: " + months);
}
else if( token.contains("days") ) {
days = Integer.valueOf(token.replace("days", ""));
System.out.println("Days are: " + days);
}
else if( token.contains("hours") ) {
hours = Integer.valueOf(token.replace("hours", ""));
}
else if( token.contains("minutes") ) {
minutes = Integer.valueOf(token.replace("minutes", ""));
}
else if( token.contains("seconds") ) {
seconds = Integer.valueOf(token.replace("seconds", ""));
}
}
Period period = new Period( years, months, weeks, days, hours, minutes, seconds, 0);
// User period to initialize new endDate
DateTime endDate = new DateTime(startDate).plus(period);
// Find duration 2 using new endDate
String duration2 = DurationFormatter.format(startDate, endDate.toDate());
// If the durations are the same, then success.
Assert.assertEquals(
"The date of " + duration2
+ " is equal to " + duration1,
duration1, duration2);
}
}
The result always output with error:
junit.framework.ComparisonFailure:
The date of 5days 23hours 5minutes 23seconds is equal to 1month 5days 23hours 5minutes 23seconds expected:<[1month ]5days 23hours 5minut...> but was:<[]5days 23hours 5minut...>
The string '[1month ]' always missing. Please check if I'm missing something in code?
Thanks
In your code, you have .appendSuffix("month", "months") where "month" is the singular form, "months" is the plural form.
Your test only parses the plural forms:
else if( token.contains("months") ) {
...
}
In this case, the test fails because it is only 1 month and therefore singular.
Update your testing code to parse both singular and plural form and it should work!
Documentation