Reputation: 153
I am trying to get the sunset time for the users in there local time. I get the sunset time in UTC from sunrise-sunset.org. Then I convert it to local time, then I account for daylight savings time and then I convert it to regular time.
The problem is it comes out hours off.
Edited For example:
In the app the user can set there location to anywhere in the world, let's say they set it to Springfield MO(USA). It returns 04:57:31 AM
, after I convert it and what not it comes out to 5:57 AM
, even though it should say 4:57 PM
. That is for API 30.
Now what makes that even more strange is if I use a API 22 phone it comes out as 7:57 PM
.
I needed to support API 21 to API 30(Android 11).
Also it keeps returning daylight savings time as on, when it's not.
public void RequestSunsetTime(String lat, String lng){
// set loading text
sunsetTimeTextView.setText(R.string.loading_text);
ProjectRepository projectRepository = new ProjectRepository();
String url = "https://api.sunrise-sunset.org/json?lat=" + lat + "&lng=" + lng + "&date=today";
projectRepository.requestDataPartTwo(url, new ProjectRepository.VolleyResponseListenerForTwo() {
@Override
public void onResponse(String UTCtime) {
// convert utc time to local time
String time = UTCtime;
System.out.println("== TIME ==" + time);
try {
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss a", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date _date = df.parse(UTCtime);
df.setTimeZone(TimeZone.getDefault());
System.out.println(">>>>>>>>>>> Time zone: " + TimeZone.getDefault());
time = df.format(_date);
System.out.println(">>>>>>>>>>> time: " + time);
// convert army time to standard time
String[] timeParts = time.split(":"); // convert to array
// fetch
int hours = Integer.parseInt(timeParts[0]);
System.out.println(">>>>> army time hours: " +hours);
int minutes = Integer.parseInt(timeParts[1]);
// --- *.getDSTSavings()* adds time for day light saving time
int timeForDST = (((TimeZone.getDefault().getDSTSavings() / 1000) / 60) / 60);
System.out.println(">>>>>>>>>>> time: " + time);
// calculate
String timeValue = "";
if (hours > 0 && hours <= 12) {
timeValue= "" + hours;
} else if (hours > 12) {
timeValue= "" + (hours - 12);
} else if (hours == 0) {
timeValue= "12";
}
if(timeForDST != 0){
int num = Integer.parseInt(timeValue);
timeValue =String.valueOf(num + timeForDST);
}
timeValue += (minutes < 10) ? ":0" + minutes : ":" + minutes; // get minutes
timeValue += (hours >= 12) ? " PM" : " AM"; // get AM/PM
time = timeValue;
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(">>>>>>>>>> Final Time: " + time);
// save
}
});
}
Thank you in advance:)
Upvotes: 0
Views: 1397
Reputation: 339472
You are working much too hard.
Never use the terrible legacy date-time classes such as SimpleDateFormat
, TimeZone
, Date
, and Calendar
classes. Use only the java.time classes.
I’m not clear on what format of text you receive. I’ll assume it is standard ISO 8601 format YYYY-MM-DDTHH:MM:SSZ. (If not, edit your Question for clarity.)
Instant instant = Instant.parse( "2022-01-23T12:34:56.123456789Z" ) ;
If desired, lop off unneeded detail.
instant = instant.truncatedTo( ChronoUnit.MINUTES ) ;
Adjust from an offset of zero hours-minutes-seconds from UTC to a particular time zone.
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // Or ‘ZoneId.systemDefault()`.
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the time of day.
LocalTime lt = zdt.toLocalTime() ;
Generate text in automatically localized format.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( Locale.CANADA_FRENCH ) ;
String output = lt.format( f ) ;
See this code run live at IdeOne.com.
These classes are built into Android 26+. For earlier Android, use the latest tooling with its “API desugaring” to access most of the java.time functionality.
Upvotes: 4