I'm writing a piece of code that I want to work even past 2038. I need to store an epoch timestamp in a map and was wondering if I am compatible going forward when I use a long long instead of an int to store tiume(NULL) or how else I best go about this? I'm aware that even using an unsigned int would give nme plenty of more room - but is that or long long the best way to go about it?
Related
I work for an organization in two locations. One of them is Chile, where daylight savings time is extremely unpredictable and often varies from year-to-year. We have an application that is dependent on time and up until now, have been using joda time. When the Chilean government decides to change daylight savings, we use joda code to set an offset to the default DateTimeZone:
/**
* Updates the default time zone, i.e. the time zone which is used as local time.
*/
private void updateDefaultTimeZone() {
if (isEmpty(Configuration.Value.TIME_ZONE_OFFSET)) {
// make the site's default time zone the current time zone for joda time,
// this should always be the case for the non-Chile site, and work for the Chile site during most of the year
DateTimeZone.setDefault(siteService.getSiteTimeZone());
} else {
// makes a user defined time zone the current time zone for joda time
// this will be used when Chile is delaying or pulling forward the transition from/to daylight
// saving time and the JVM is therefore not able to calculate the local times appropriately
Integer offset = getInteger(Configuration.Value.TIME_ZONE_OFFSET);
DateTimeZone.setDefault(DateTimeZone.forOffsetHours(offset));
}
}
We're trying to transition our code base from joda time to Java 8 time, but I have really no idea the classes that are involved in doing something similar. I'm guessing perhaps ZoneRules, but I'm not sure. Does anyone have any hints as to how to most cleanly accomplish this?
Additionally, what is the best way of converting units in Java 8 time? Say I have 24 hours and I want to convert it into days. (I ask because in this case, it seems many methods work with milliseconds and I want to work with hours, but think there must be a better built-in way to convert than to do the arithmetic by hand.)
Use java.util.TimeZone.setDefault(TimeZone). Because JSR-310 java.time.* is integrated with the JDK, there is no need for a separate method.
(To convert units, you may find it easiest to use TimeUnit, but perhaps a separate more focussed question would help you there.)
JodaStephen has said it. He’s the lead developer of both Joda-Time and java.time, so definitely the authority here. I add just some supplementary thoughts.
Consider not relying on a default time zone
The default time zone of the JVM can be changed at any time from another part of your program and from other programs running in the same JVM. So relying on it is fragile. java.time (Java 8 time) consistently offers you the possibility of specifying time zone for all time zone sensitive operations. My habit is to use this. So my suggestion is that you store the time zone somewhere in your program where you alone control who’s tampering with it and code your date and time operations to use this stored setting and not the default time zone of the JVM.
If you still rely on the default: The TimeZone class has a bad design flaw. This would look sound to me at first sight:
TimeZone.setDefault(TimeZone.getTimeZone("America/Santiago_de_Chile"));
It isn’t! Look at the output from
System.out.println(TimeZone.getDefault().getID());
GMT
Extremely confusing IMHO. The correct time zone ID is America/Santiago, not America/Santiago_de_Chile. So we should have expected an IllegalArgumentException or similar here. Instead TimeZone just tacitly gives us a completely wrong time zone, GMT.
Instead use:
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("America/Santiago_de_Chile")));
Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: America/Santiago_de_Chile
Time unit conversions
Like JodaStephen I routinely use TimeUnit for time unit conversions, but I try to remember to think twice before doing so.
System.out.println(TimeUnit.HOURS.toDays(24));
System.out.println(TimeUnit.DAYS.toHours(400_000_000_000_000_000L));
1
9223372036854775807
It looks right, doesn’t it? It isn’t either! For two reasons:
A day is not always 24 hours. When Chile goes from standard time to summer time (DST) or vice versa, a day is 23 or 25 hours.
The conversion doesn’t report long overflow. The latter conversion overflows. TimeUnit tacitly gives us the closest value that can fit in a long, in this case the value of Long.MAX_VALUE.
When you know what you are doing and you know your conversions don’t overflow, you may use it. I also do most of my int math without checking for overflow. java.time offers a nice converstion that does check for overflow:
System.out.println(Duration.ofDays(400_000_000_000_000_000L).toHours());
Exception in thread "main" java.lang.ArithmeticException: long overflow
I even find this code a bit more readable than the TimeUnit code.
I am wondering if there is a library method out there that will take a time string of unknown format and reformat it into a standard format (i.e. HHMM). Examples of the type of thing I am getting from websites are.
1030 10:30 10pm 10PM 1030PM 10pm
1030PM 1030p.m. 1030pm. 930 930am
9am 8.30 8.30pm
and I am sure there are others.
I started to write a method and it's getting there (https://gist.github.com/funkytwig/b47551e98e8698ebb59310286982a6ce) but wondering if there is already one around. It is worth mentioning I have come across websites where the times in the same list (i.e. event listing) are not consistent, I think they are hand typed into a text field when input.
Just to clarify I am wondering if there is a method in a library already existing, i'm not asking people to debug my code. I'm just sharing it to show what I have done to try to solve the problem, and you will see why I am hoping there is a library.
Try chronic. It can parse a whole lot of time formats, including the ones that you gave.
Can I change a file's creation time (apparently also known as birth time or btime) in Go, and if so, how?
I've found a couple of ways to deal with file times in Go, including os.Chtimes and this package — however, the former does not support btime, and the latter seems to deal only with reading the dates, not changing them.
I'm looking for a Windows solution, though a general answer won't hurt either.
So, the flowplayer documentation says that there are two ways to get the current play time of a Player object. getTime() and getStatus().time. Unfortunately, both of those return int's (in seconds), and I am creating a screen-shot and need to get the current timestamp in 1/10th's of a second (and 1/100 is even better). Is it possible to get a more accurate value (ideally in JS, I can manage AS if necessary but that is annoying)
No, apparently there is no way to retrieve that information.
I'm currently evaluating the use of ADO.NET for a C++ application that currently uses plain old ADO. Given that we're redoing the whole database interaction, we'd like to determine if using the more modern and actively developed technology of ADO.NET would be beneficial.
After some measurements it appears that for certain test queries that retrieve a lot of rows with few columns that all contain strings, ADO.NET is actually about 20% slower for us than using plain ADO. Our profiler suggests that the conversion of System.String results into the std::wstring used by the application is one of the bottlenecks. I can't switch any of the upper layers of the application to using System.String, so we are stuck with this particular conversion.
A rough outline of the code looks like this:
System::Data::SqlClient::SqlCommand^ sqlCmd =
gcnew System::Data::SqlClient::SqlCommand(cmd, m_DBConnection.get());
System::Data::SqlClient::SqlDataReader^ reader = sqlCmd->ExecuteReader();
if (reader->HasRows)
{
using namespace msclr::interop;
while (reader->Read())
{
std::vector<std::wstring> results;
for (int i=0; i < reader->FieldCount; ++i)
{
std::wstring col_data;
TypeCode type = Type::GetTypeCode(reader->GetFieldType(i));
switch (type)
{
// ... omit lots of different types
case TypeCode::String:
{
System::String^ tmp = reader->GetString(i);
col_data = marshal_as<std::wstring>(tmp);
}
break;
// ... more type conversion code removed
}
results.push_back(col_data);
}
// NOTE: Callback into native result processing code
ResultsCallback(results);
}
I've spent a lot of time reading up on the various ways of getting a std::wstring out of the System.String and measured most of them. They all seem to perform roughly similar - we're talking decimal points in the percentage of CPU usage. In the end I simply settled for using marshal_as<std::wstring> as it's the most readable and appears to be as performant as the other solutions (ie, using PtrToStringChars or the method described in MSDN here).
Using the DataReader works very well from a conceptual point of view as most of the processing we do on the data is row oriented anyway.
The only other slightly unexpected bottleneck I noticed is the retrieval of the TypeCode for the results columns; I'm already planning to move that outside the main results processing loop and only retrieve the type codes once per query result.
After this lengthy introduction, can anybody recommend a less costly way to convert the string data from a System.String to a std::wstring or am I already looking at the optimum performance here? I'm obviously more looking for slightly out of the ordinary ways given that I've already tried all the ordinary ones...
EDIT: Looks like I fell into a trap of my own making here. Yes, the code above is about 20% slower than the equivalent plain ADO code in Debug mode. However switching it into Release mode, the bottleneck is still measurable but the ADO.NET code above is suddenly almost 50% faster than the older ADO code. So while I'm still concerned a little about the cost of the string conversion, it's not as big in Release mode as it first appeared.
I don't see there being any way to optimize that, since the implementation of marshal_as<std::wstring> just grabs the internal C string and assigns it to an std::wstring. You can't get much more efficient than that.
The only solution I can see is splitting up your rows and having N threads process them in parallel. The only issue is that you would need to reserve enough space in your vector to prevent a resize from taking place during processing, but that looks easy enough.
If you're using Visual Studio 2010, I think the C++0x threading library would be sufficient for this task, though I'm not sure how much (if any) is implemented in Visual Studio so far.