I have an excel document with times listed as "02:30" ... however, when iterating through them using NPOI, the DateCellValue flips to "02:29:59" ... This first happens on 1/1/2019 (which correctly stores as "02:30") but then on 1/2/2019 it flips to "02:29:59" ... Does anyone know how to have it simply get the value of the cell without trying to do any voodoo to it? It's obviously taking into account perhaps a leap second, or something? It is, however, clear as day in Excel as "02:30", and at my breakpoint with:
[Model].DepartureDttm = row.GetCell(j).DateCellValue [1/2/2019 2:29:59 AM]
You're not the only one that have faced this problem. Here's a good answer.
You can use the DateUtil.GetJavaDate coming with NPOI to resolve this issue . You can create this basic extension method:
public static class Extensions
{
public static DateTime DateCellValueRounded(this ICell cell)
{
return DateUtil.GetJavaDate(cell.NumericCellValue, false, TimeZone.CurrentTimeZone, true);
}
}
Then use it like this:
DateTime date = row.GetCell(index).DateCellValueRounded;
GetJavaDate signature (the last parameter set to true does the job):
public static DateTime GetJavaDate(double date, bool use1904windowing, TimeZone tz, bool roundSeconds);
Related
I've added the Excel upload feature to the Details section of the Employee Time Card screen (EP305000). This works fine, but if the 'Time' field (which is actually date_time, but I can't find that in the DAC - only 'Date') isn't specified in the upload, it defaults to midnight (12:00 AM). I want this to default to 8:00 AM, but I'm not sure how to do this, since the field is actually a date. It doesn't seem like I can just use [PXDefault] or anything simple like that.
How can I accomplish this?
Thanks...
Here's the solution I came up with, using the 'RowInserted' event:
protected void EPTimeCardDetail_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
var eptcd = (EPTimecardDetail)e.Row;
DateTime theDate = (DateTime)eptcd.Date;
DateTime MyDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, 8, 0, 0);
eptcd.Date = MyDate;
}
In the app I am making when the view loads I want an object to be deleted in the background whenever the current time is greater than the given time. Otherwise if the current time is less than the given time the object loads normally. This is working fine for any time within the hour for example if the current time is 9:30 PM and the given time is 9:45 PM it works fine, but if the current time is 9:30 PM and the given time is 11:45 PM for some reason it doesn't know how to compare the hour so it doesn't work. Here is my code:
if timeString > End {
self.SpotterMap.removeAnnotation(SpotAnnotation)
let endTime = End
let query:PFQuery = PFQuery(className: "SpotInfo")
query.whereKey("spotendtime", equalTo: endTime)
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let objects = objects {
for object in objects {
object.deleteInBackground()
}
}
})
print ("spot removed")
}
Can anyone give a solution to my problem?
Thanks
If you are going to work with times, you need to work with the NSDate type representation of your dates for the best accuracy, not a string one.
You will need to change your parse class spotInfo and add a column of type date, lets say you call it "realSpotEndTime".
To compare the times use .compare directly on the NSDates, if the dates return true when ordered ascending, it means that the first date comes before the second one. So your if statement would become;
(note: to get the real current time, you need to instantiate NSDate() right before comparison)
If this returns true and executes it means that the current time on the phone is less compared to the End time, remember, End needs to be in NSDate type as well, not string
let currentTime = NSDate()
//currentTime < End
if (currentTime.compare(End) == .OrderedAscending) {
...
query.whereKey("realSpotEndTime", lessThanOrEqualTo: currentTime)
}
or, alternatively you could do check if the current time is past the end time by
//End < currentTime
if (End.compare(currentTime) == .OrderedAscending) {
// fix parse query here
}
I am giving a try to MonoTouch and MonoTouch.Dialog and was wondering what would be the best way to create a Time entry element for minutes and seconds only. The TimeElement only seems to support hours and minutes.
I am very new to the whole framework, so I am wondering if there a way to create a text entry element with sort of a "##:##" mask and use a numeric keypad to populate the minutes and seconds?
A cooler option would be to use a section that would take the user to a view with two "Picker Views" (rotating wheels) for minutes and seconds, but I am not there yet.
Thanks in advance
MonoTouch.Dialog's source code is available on Github (https://github.com/migueldeicaza/MonoTouch.Dialog/tree/master/MonoTouch.Dialog).
There, have a look at the implementation of the DateElement (https://github.com/migueldeicaza/MonoTouch.Dialog/blob/master/MonoTouch.Dialog/Elements.cs#L1827)
To get you a TimeElementMinutesSeconds, all you have to do is (untested) abuse the count down mode. It will offer hours and minutes, but you can just interpret them as minutes and seconds:
public class TimeElementMinutesSeconds : DateTimeElement {
public TimeElementMinutesSeconds (string caption, DateTime date) : base (caption, date)
{
}
public override string FormatDate (DateTime dt)
{
DateTime dtLocal = GetDateWithKind (dt).ToLocalTime ();
return string.Format("{0:##}:{1:##}"dtLocal.Hours, dtLocal.Minutes);
}
public override UIDatePicker CreatePicker ()
{
var picker = base.CreatePicker ();
picker.Mode = UIDatePickerMode.CountDownTimer;
return picker;
}
}
If that doesn't get you near enough, you can create your own picker and return that instead.
Part of an on premise app I am moving to the cloud, displays TV Scheduling information from a json source. The core data uses an offset in seconds from a start date to get it's start times which is all fine as these are all int UTC format.
The problem arises in the movement to the cloud.
The on premise app was situated in the UK so the locale is UntedKingdom and the TV times were correctly output using
return programmeStart.AddHours(programmeStart.IsDaylightSavingTime() ? 1 : 0);
However, having now moved to the cloud, the functionality for IsDaylightSavingTime, no longer returns true due to data centers being BST Agnostic.
Been racking my brains for a way to try and sort this.
Is there a quick and easy way to set what locale your hosted service runs under in Azure, or is the best solution to create an extension method that reads the boundries of when BST runs from and to, and then return true or false from there for example
public static class DateTimeExtension
{
public static bool IsMyDaylightSavingTime(this DateTime timeToTest)
{
if(timeToTest >= GetConfig("bstStart") && timeToTest <= GetConfig("bstFinish"))
{
return true;
}
return false;
}
}
And the maintaing the config values of bst changing as they move?
Thanks
You can't change the timezone of the Azure servers - there's lots going on that assumes UTC is the current setting.
You should be able to get hold of the UK timezoneinfo by string, e.g.:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
After you've done that, then you can use the framework method TimeZoneInfo.IsDaylightSavingTime http://msdn.microsoft.com/en-us/library/bb460642.aspx
tzi.IsDaylightSavingTime(DateTime.Now);
Why can't you simply return UTC and let the client translate that per their locale?
Edit: Here is code
var offset = TimeZoneInfo.GetSystemTimeZones()
.Where(z => z.Id == "GMT Standard Time")
.Single()
.GetUtcOffset(DateTime.UtcNow)
SPListItem.GetFormattedValue seems to have a strange behavior for DateTime fields.
It retrieves the DateTime value through SPListItem's indexer which according to this MSDN article returns local time.
Here's a snippet from Reflector
public string GetFormattedValue(string fieldName)
{
SPField field = this.Fields.GetField(fieldName);
if (field != null)
{
return field.GetFieldValueAsHtml(this[fieldName]);
}
return null;
}
So it uses SPListItem's indexer to retrieve the value and than SPFields.GetFieldValueAsHtml to format the value. GetFieldValueAsHtml seems to assume the date is in UTC and convert it to local time no matter what kind it is. (Reflector shows that it uses GetFieldValueAsText which uses value.ToString() but for some reason it assumes the time to be UTC.)
The end result is that the string representation on a time field obtained trough listItem.GetFormattedValue() (at least in my case) is incorrect, being local time + (local time - UTC).
Have anybody encountered the same issue with SPListItem.GetFormattedValue() and what was your workaround?
Converting the date back to universal time before calling GetFieldValueAsHtml works just fine.
DateTime localTime = (DateTime)item["DueDate"];
// this is local time but if you do localDateTime.Kind it returns Unspecified
// treats the date as universal time..
// let's give it the universal time :)
DateTime universalTime = SPContext.Current.Web
.RegionalSettings.TimeZone.LocalTimeToUTC(localTime);
string correctFormattedValue =
item.Fields["DueDate"].GetFieldValueAsHtml(universalTime);
I have had a recognised bug with the date conversion from UTC in SharePoint. It was fixed in SP1.