I am writing an application to receive past stock data in java.
I am using a Calendar to chose the to and from dates when calculating a six day average however this is not working due to the to calendar being the same as the from despite subtracting days in the latter...
private BigDecimal calcMovingAvg(int days, Calendar start){
Calendar to = start;
int temp = Functions.weekdays(start.getTime(), days);
temp = temp - (2 * temp);
start.add(start.DAY_OF_MONTH, temp);
BigDecimal d = new BigDecimal(String.valueOf(days));
List<HistoricalQuote> histQuotes = null;
try {
//Calling a method to get stock history between start and to date
histQuotes = stk.getHistory(start, to, Interval.DAILY);
System.out.println(histQuotes);
} catch (IOException e) {
e.printStackTrace();
}
Start is already defined and working
I save to = start so as to have an end date when taking the previous 6 days for averaging
Functions.weekdays calculates how many of those 6 days were actually weekdays (business days) and adjusts the number accordingly (temp is the number of days needed to get 6 business days).
When comparing, I am getting start == to, why is start not changing?
Calendar to = (Calendar) start.clone();
int temp = Functions.weekdays(start.getTime(), days);
temp = temp - (2 * temp);
start.add(start.DAY_OF_MONTH, temp);
The calendar was using the same instance. Cloning the calendar solved the issue as it created two separate entities.
java.time
This work is easier with the java.time framework built into Java 8 and later. Avoid using the old date-time classes such as java.util.Calendar as they haven proven to be poorly designed and troublesome.
Immutable Objects
The java.time classes use immutable objects, generating new objects based on the old ones’ values rather than changing (”mutating“) the original. This approach prevents the problem encountered in the Question.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime later = now.plusWeeks( 1 ); // Generates a second object without modifying the first.
Convert
Best to avoid the old classes entirely, including java.util.Date and java.util.Calendar. But if you must, you can convert.
New methods have been added to the old classes to facilitate conversion.
Call GregorianCalendar::toZonedDateTime to generate an equivalent ZonedDateTime object. I your Calendar object is indeed a GregorianCalendar, downcast.
if( cal instanceof GregorianCalendar ) {
GregorianCalendar gCal = ( GregorianCalendar ) cal; // Cast. Down-casting from interface to concrete class.
ZonedDateTime zdt = gCal.toZonedDateTime();
}
Call the static method GregorianCalendar.from( ZonedDateTime) to get a GregorianCalendar object (which implements the Calendar interface) from a ZonedDateTime.
java.util.Calendar cal = java.util.GregorianCalendar.from( later );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I'm looking to see if there is a better way in obtaining the same result as the following code:
Calendar date = Calendar.getInstance();
date.setTimeInMillis(System.currentTimeMillis());
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
I'm using this to be able to compare the difference in days between two dates. I am currently coding for target API 24 and am not interested in using Joda Time for such a simple task.
I've come up with the following function, but would love to hear if there is a simpler, perhaps built in, method for either zeroing out the date or an entire different method for getting the amount of days between two dates.
private long getFlatDateInMillis() {
Calendar currentDate = Calendar.getInstance();
currentDate.setTimeInMillis(System.currentTimeMillis());
currentDate.set(Calendar.HOUR_OF_DAY, 0);
currentDate.set(Calendar.MINUTE, 0);
currentDate.set(Calendar.SECOND, 0);
currentDate.set(Calendar.MILLISECOND, 0);
return currentDate.getTimeInMillis();
}
That way, I could quickly use:
Calendar date = getFlatDateInMillis();
I just want to make sure I'm not missing anything that is simpler, already pre-defined.
Thank you!
The correct way to do this is with the java.time.LocalDate class. It stores only the date, not the time, and it has a now() static method, which returns the current day.
LocalDate today = LocalDate.now();
If you're looking at Android, this was added at API level 26, but there are other ways of using the "new style" date classes with Android, such as the ThreeTen-Backport library.
tl;dr
ChronoUnit.DAYS.between( // Calculate elapsed time between a pair of `LocalDate` date-only objects. Returns a total number of elapsed days.
( (GregorianCalendar) myJavaUtilCal ) // Cast your legacy `java.util.Calendar` object to the subclass `java.util.GregorianCalendar`, also legacy.
.toZonedDateTime() // Convert from legacy `GregorianCalendar` to modern `ZonedDateTime` class.
.toLocalDate() , // Extract the date-only value, a `LocalDate`, lacking time-of-day and lacking time zone.
otherLocalDate // Compare to some other `LocalDate` object.
) // Returns a `long` number of days. Uses Half-Open approach where the beginning is *inclusive* while the ending is *exclusive*.
Details
The Answer by Kareem is correct. Some more thoughts here.
Is there a better way to zero out Calendar date?
Yes, there is a better way: don’t.
Trying to clear out the time-of-day on a date+time types is the wrong approach; use a date-only type instead (LocalDate).
And don’t use the troublesome old legacy classes such as Calendar, Date, SimpleDateFormat as they are now supplanted by the java.time classes.
the difference in days between two dates
First convert your legacy Calendar object to the modern ZonedDateTime class. To convert, call new methods added to the old classes.
GregorianCalendar myGregCal = (GregorianCalendar) myJavaUtilCal ; // Cast from superclass to subclass.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // Convert from legacy class to modern class.
Extract the date-only value.
LocalDate ld = zdt.toLocalDate() ; // Extract date-only object from date-time object.
Calculate elapsed time in days
long days = ChronoUnit.DAYS.between( ld , otherLd ) ;
Or represent the elapsed time as a Period.
Period p = Period.between( ld , otherLd ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
EDIT: Thanks to Basil and Kareem, I've updated to the following code (so, so much easier):
Added to gradle.build:
compile 'com.jakewharton.threetenabp:threetenabp:1.0.5'
Then, in my activity, etc,
AndroidThreeTen.init(this);
LocalDate today = LocalDate.now();
LocalDate anotherDay = LocalDate.of(2019, 3, 25);
long dayDifference = ChronoUnit.DAYS.between(today, anotherDay); //dayDifference = 365
One thing of note is that Calendar references months starting at 0 index, whereas LocalDate references months starting at 1 index.
I wan't to convert a string Calendar Object (calendar.toString()) to calendar object.
I tried this solution but it show in console the date of the day '12-05-2017' not '02-02-2017'
String calendar object format:
java.util.GregorianCalendar[time=1485993600000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Africa/Casablanca",offset=0,dstSavings=3600000,useDaylight=true,transitions=102,lastRule=java.util.SimpleTimeZone[id=Africa/Casablanca,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=10800000,endTimeMode=0]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2017,MONTH=1,WEEK_OF_YEAR=5,WEEK_OF_MONTH=1,DAY_OF_MONTH=2,DAY_OF_YEAR=33,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(new Date("2017/02/02"));
System.out.println("calendar : "+calendar.getTime());
try {
GregorianCalendar gc = new GregorianCalendar();
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
System.out.println("calendar : "+calendar.getTime());
gc.setTimeZone(TimeZone.getTimeZone(calendar.toString()));
System.out.println("tme zone : "+gc.getTimeZone());
System.out.println("calendar : "+calendar.getTime());
System.out.println("calendar : "+calendar.toString());
System.out.println(formatter.format(gc.getTime()));
}
catch(Exception e) {
//If exception, return server TimeStamp
}
Any help please
If that were me, I’d look at all the setters of both Calendar and GregorianCalendar and see if I thought I could extract the values needed for the setters from the string. “time=1485993600000” should give you the most important information, the time, and you can feed it into setTimeInMillis(). You ought to be able to get a time zone out of “Africa/Casablanca”. And so forth. You can probably use regular expressions for extracting the fields from the string.
You’d probably have to live with not covering all cases. Your particular GregorianCalendar seems to contain a sun.util.calendar.ZoneInfo and a java.util.SimpleTimeZone; I don’t know whether that is always the case nor what other possibilities there are.
The strict test of your attempt is easy: just call toString() again on your newly constructed instance and see if you get the same string. The difficulty comes if you accept some differences and you need to determine whether the actual differences lie within what you have decided to accept.
Or really, I wouldn’t want to bother if I could avoid it. I’d see if I could find an easier task or an easier way to obtain what you are really trying to obtain. As I already said in a comment, one may use java.time.LocalDate instead of GregorianCalendar. LocalDate.parse() will readily parse the string from LocalDate.toString(), and the problem is solved. Just to give one example of another way to look at it.
In your code, you have two separate GregorianCalendar objects - one called calendar and one called gc. You're setting one calendar object to the date that you want, then printing out the other one.
Thanks #Ole , I finally found the solution and it works.
Calendar calendar = Calendar.getInstance();;
calendar.setTime(new Date("2017/02/02"));
String[] ds = calendar.toString().split("=");
String[] ds2 = ds[1].split(",");
try {
Calendar cal = Calendar.getInstance();;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
cal.setTimeInMillis(Long.valueOf(ds2[0]));
System.out.println(formatter.format(cal.getTime()));
}
catch(Exception e) {
}
java.time
You are using terrible old classes that are now supplanted by the much superior java.time classes.
Instantiate a LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = LocalDate.parse( "2017-02-02" ) ;
To generate a string in standard ISO 8601 format, call toString.
String output = ld.toString() ;
2017-02-02
For other formats use the DateTimeFormatter class.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ;
String output = ld.format( f ) ;
02-02-2017
Your Question is not clear. If the problem is that your code is being handed a GregorianCalendar object, convert it to java.time.ZonedDateTime. Call new conversion methods added to the old classes.
if( myCalendar instanceOf GregorianCalendar ) {
ZonedDateTime zdt = myCalendar.toZonedDateTime() ;
}
Extract the date-only value you desire, as a LocalDate.
LocalDate ld = zdt.toLocalDate() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I'm having an issue with the Java Calendar add() functionality. The give or take is used to provide a roundabout date for dates to depart on a travel site.
end.add(Calendar.DATE, Integer.parseInt(giveOrTake));
The code is above and the test condition I'm using is to choose 29/07/2012 as the date and 3 days give or take. According to the documentation this should come out as 01/08/2012 but it comes out at 01/07/2012.
I've checked giveOrTake when it's passed to the method and it's fine so I have no idea what is going on. I can hardcode the giveOrTake value and still get the error.
Works for me:
import java.util.*;
public class Test {
public static void main (String []args) {
Calendar calendar = Calendar.getInstance();
calendar.set(2012, Calendar.JULY, 29);
calendar.add(Calendar.DATE, 3);
System.out.println(calendar.getTime()); // August 1st
}
}
My guess is that you've got the month wrong before calling add - note how my call to set above uses 6 as the month, because the call uses 0-based month numbers.
Note that as per my comment on the question, you'd be much better off moving to Joda Time if you can...
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
Also, you are using a date-time object to represent a date-only value, a misfit.
Using java.time
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = LocalDate.of( 2012 , 7 , 29 ) ;
LocalDate threeDaysLater = ld.plusDays( 3 );
ld.toString(): 2012-07-29
threeDaysLater.toString(): 2012-08-01
See code run live in IdeOne.com.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
It was an issue with the date format. It was set as yyyymmdd when it should have been 'yyyyMMdd'.
I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I'm trying to add some minutes to a date using plusMinutes, but it just doesn't add anything at all:
Here's the code:
String currentDate ;
SimpleDateFormat myFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date1= null;
DateTime dt;
currentDate ="27/12/2010 11:29" ;
try {
date1= myFormat.parse(currentDate);
} catch (ParseException ex) {
ex.printStackTrace();
}
dt = new DateTime(date1);
dt.plusMinutes(30);
Javadoc says
Returns a copy of this datetime plus the specified number of millis.
so
do something like
dt = new DateTime(date1);
dt = dt.plusMinutes(30);
System.out.println(""+dt);
Beauty of joda is that most of their classes are immutable like String in Java. Update operations doesn't change the original object. So plusMinutes(...) returns a new copy of the DateTime with the minutes added which you can assign to a new variable as shown below.
DateTime newDt=dt.plusMinites(30);
System.out.println(newDt);
I think you want dt = dt.plusMinutes(30);
plusMinutes returns a calculated dateTime. It does not modify the dateTime it is called on.
tl;dr
java.time.LocalDateTime.parse(
"27/12/2010 11:29" ,
DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm" )
).plusMinutes( 30 )
2010-12-27T11:59
Tip: If you intended this to be a moment, a specific point on the timeline, apply the context of a time zone (ZoneId) to get a ZonedDateTime.
java.time
Your Question uses the troublesome old date-time classes from the earliest versions of Java, and your Question uses the Joda-Time project which is now in maintenance mode. Both have been supplanted by the java.time classes built into Java 8 and later.
Your string input lacks an indicator of time zone or offset-from-UTC. So parse as a java.time.LocalDateTime.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm" ) ;
LocalDateTime ldt = LocalDateTime.parse( "27/12/2010 11:29" , f ) ;
ldt.toString(): 2010-12-27T11:29
Note that you do not have an actual moment, this is not a specific point on the timeline. This is only a vague idea about potential moments along a range of about 26-27 hours. To determine an actual moment, place this in the context of a time zone (or offset): ZonedDateTime zdt = ldt.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;.
Add your minutes.
LocalDateTime later = ldt.plusMinutes( 30 ) ;
later.toString(): 2010-12-27T11:59
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.