Convert DateTime to another timezone - windows-phone-7

How do I convert a DateTime from the local timezone returned by DateTime.Now to another timezone than Utc. On desktop we have the TimeZoneInfo.ConvertTimeBySystemTimeZoneId(), but it's not available on windows phone!
This java snippet shows roughtly what I want to do
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
TimeZone tz = TimeZone.getDefault();
format.setTimeZone(TimeZone.getTimeZone("GMT"));
str = format.format(new Date());

This is not possible to do using the system libraries as there is no way to create TimeZoneInfo objects other than local and utc. They have also sealed the class.
You can however use this simple library to enable conversion to non-local time zones.
https://nuget.org/packages/WinRTTimeZones
Use it like this:
using TimeZones;
public void ConvertTime()
{
// Get the time zone we want
var tz = TimeZoneService.FindSystemTimeZoneById("Central Standard Time");
var dt = new DateTime(1990, 7, 1, 12, 0, 0, DateTimeKind.Utc);
// This time will be central time
var local = tz.ConvertTime(dt);
}
When the DateTime is converted it is an easy exercise to format it as you want. I recommend to format the date in the local format (not the local timezone) to make easy for the user to understand the date.

Use it like this:
public String getNationTime(String Zone)
{
DateTime todayutc = DateTime.UtcNow;
string todaydate = todayutc.ToShortDateString();
string todaytime = todayutc.TimeOfDay.ToString().Split('.')[0];
Zone = Zone.Replace("GMT", "");
if (Zone.Length == 0)
return todaytime;
int zoneHour = int.Parse(Zone.Split(':')[0]);
int zoneMin = int.Parse(Zone.Split(':')[1]);
TimeSpan diff = new TimeSpan(zoneHour, zoneMin, 00);
todayutc = todayutc.Add(diff);
return todayutc.TimeOfDay.ToString().Split('.')[0];
}

Related

JDK7- SimpleDateFormat vs JDK8-DateTimeFormatter, "2019 02" is parsable with the old but not the new one

I am using the same format "yyyyMM" in SimpleDateFormat and DateTimeFormatter. I have set the leniency in both formatters.
Though, SimpleDateFormat is able to parse "2019 02" but not DateTimeFormatter. I have tried setting multiple formatters but no luck.
It must be a simple way but I am not able to figure it own. Does any one know how to restore the behavior with DateTimeFormatter?
String dateString = "2018-11";
String format = "yyyyMM";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
simpleDateFormat.setLenient(true);
try {
Date parse = simpleDateFormat.parse(dateString);
System.out.println(parse);
System.out.println(format + ":parsed: true : java7");
} catch (ParseException e) {
System.out.println(format + ":parsed: false : java7");
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withResolverStyle(ResolverStyle.LENIENT);
try {
TemporalAccessor parse = formatter.parse(dateString);
System.out.println(parse.toString());
System.out.println(format + ": parsed: true : java11");
} catch (Exception e) {
System.out.println(format + ":parsed: false : java11");
e.printStackTrace();
}
You could create a DateTimeFormatter with a complex pattern with a DateTimeFormatterBuilder:
For example to parse yyyyMM, yyyy-MM and yyyy MM you could use:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR_OF_ERA, 4)
.optionalStart().appendLiteral('-').optionalEnd()
.optionalStart().appendLiteral(' ').optionalEnd()
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.toFormatter();
But this format is also strict because the year and the month have a fixed width else the optional literals doesn't work.
You can add .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) to simply parse a LocalDate.

How to display Date like device date time format in Android

I have a date:
var date = new DateTime(2017,6,14,13,0,0);
and a textview to display it.
I'd like to display as '14/06/2017 13:00' when I set Date and time of the device to 'Use 24-hour format'
and '16/06/2017 1:00 PM' when I un-check 'Use 24-hour format'.
How can I do?
Thank you!
On Xamarin.Android it is a bit different than on Android as described in Muhammads answer:
var date = new DateTime(2017, 6, 14, 13, 0, 0);
var is24hour = Android.Text.Format.DateFormat.Is24HourFormat(this);
var format = is24hour ? "dd/MM/yyyy HH:mm" : "dd/MM/yyyy hh:mm tt";
var dtString = date.ToString(format);
You can use following code to convert you date object in specific format
SimpleDateFormat dateFormat;
if (android.text.format.DateFormat.is24HourFormat(YourActivityName.this)) {
// 24 hour format
dateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm");
}
else
{
// 12 hour format
dateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
}
String newDate= dateFormat.format(date);
myTextView.setText(newDate);

Getting previous instant with given time of day

I have a wake-up time at 7:45. I want my code to return the previous moment in time when this was the local time (ie. the previous wake-up time)
I know I can do this:
LocalTime wakeUpTime = LocalTime.of(7, 45);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime todaysWakeUpTime = now.with(wakeUpTime);
ZonedDateTime lastWakeUpTime;
if(todaysWakeUpTime.isAfter(now)){
// e.g. it is now 4:30, so wake-up is still to come,
// return the one from yesterday
lastWakeUpTime = todaysWakeUpTime.minusDays(1);
} else {
// e.g. it is now 11:30, so wake-up for today is already past
lastWakeUpTime = todaysWakeUpTime;
}
System.out.println(lastWakeUpTime);
Is there a cleaner version, e.g. using temporal adjusters, which better conveys the intent (getting the last of these times)?
A TemporalAdjuster can be written that allows the code to read as:
LocalTime wakeUpTime = LocalTime.of(7, 45);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime lastWakeUpTime = now.with(previousTime(wakeUpTime));
Somewhere you need to write a static method that implements the adjsuter:
public static TemporalAdjuster previousTime(LocalTime time) {
return temporal -> {
// logic to find the previous occurrence of the time
};
}
Implementing the logic will require decisions around what to do when the input is different kinds of temporals, eg LocalDate (no time, so can't work), LocalTime (no date, so nothing earlier), ZoneDateTime (what about DST changes), Instant (no date or time without a time-zone).
Based on the #JodaStephen 's answer (thanks!), here is my adjuster (for reference):
public static TemporalAdjuster previousTime(LocalTime time){
return (temporal) -> {
if (temporal instanceof ZonedDateTime) {
ZonedDateTime zdt = (ZonedDateTime) temporal;
ZonedDateTime newTime = zdt.with(time);
if(newTime.isAfter(zdt)){
newTime = newTime.minusDays(1);
}
return newTime;
} else {
throw new DateTimeException("This adjuster only handles ZonedDateTime");
}
};
}

UILocalNotification Wrong time zone

When creating a new UILocalNotification and scheduling a notification, the time gets changed due to the timezone. I the date i set gets changed by UiLocalNotifcation to the timezone. which i don't want to happen
public static void RegisterLocalNotification(ServiceModel.Types.ParkingTicket parkingTicket)
{
if (parkingTicket == null || parkingTicket.ExpiringSoon) return;
var startDate = parkingTicket.UtcStart.ToLocalTime();
NSDate nsStartDate = startDate.AddMinutes(parkingTicket.Duration - 10).UtcDateTimeToNSDate();
var notification = new UILocalNotification
{
FireDate = nsStartDate,
TimeZone = null,
AlertAction = Resources.Strings.ExtendTicket,
AlertBody = string.Format
(Resources.Strings.FormattedExpiringMessage,
parkingTicket.TimeLeft.Description(false),
parkingTicket.Address,parkingTicket.Car.RegistrationNumber),
RepeatInterval = 0,
HasAction = true,
UserInfo = GetDictionaryFromParkingTicket(parkingTicket),
SoundName = UILocalNotification.DefaultSoundName,
ApplicationIconBadgeNumber = 1
};
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
public static NSDate UtcDateTimeToNSDate(this DateTime utcDateTime)
{
var reference = new DateTime(2001, 1, 1, 0, 0, 0);
return NSDate.FromTimeIntervalSinceReferenceDate((utcDateTime - reference).TotalSeconds);
}
I have tried using TimeZone = NSTimeZone.LocalTimeZone.
You're converting a UTC date to a local date:
var startDate = parkingTicket.UtcStart.ToLocalTime ();
then you're treating the local date as a UTC date, thereby doing the conversion twice:
NSDate nsStartDate = startDate.AddMinutes(parkingTicket.Duration - 10).UtcDateTimeToNSDate();
Just do this instead:
var startDate = parkingTicket.UtcStart;
var nsStartDate = (NSDate) startDate.AddMinutes (parkingTicket.Duration - 10);
The explicit NSDate conversion will do the right thing.

What's the correct way to constrain a Date property?

The following constraint is unreliable because new Date() will only be evaluated once, leaving you with a stale max date.
class Foo {
Date date
static constraints = {
date max: new Date()
}
}
So how do you reliably constrain a Date?
Assuming the date cannot be greater than the current date of validation:
static constraints = {
date(validator: { val, obj -> val <= new Date() })
}
Grails validator

Resources