Formatting date/time in custom timezone in C++ - c++

I have a requirement to create a custom timezone (New York + 7 hours with US DST setting) and parse/format date using this.
In Java I would typically do this:
TimeZone tz = TimeZone.getTimeZone("America/New_York"); // Get new york tz
tz.setRawOffset(tz.getRawOffset() + 7 * 3600 * 1000); // add 7 hrs
DateFormat nyp7 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
nyp7.setTimeZone(tz);
DateFormat utc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utc.setTimeZone(TimeZone.getTimeZone("UTC"));
// US DST not in effect, NY is UTC-5, NY+7 is UTC+2
// below result is "2013-03-01 14:34:55"
nyp7.format(utc.parse("2013-03-01 12:34:55"));
// US DST in effect, NY is UTC-4, NY+7 is UTC+3
// below result is "2013-04-01 15:34:55"
nyp7.format(utc.parse("2013-04-01 12:34:55"));
How to do equivalent in C++? I've been digging boost date time library but I'm lost.

Found the solution by creating a custom timezone:
using namespace boost;
using namespace local_time;
using namespace gregorian;
using posix_time::time_duration;
using posix_time::ptime;
// Create a new timezone names
time_zone_names tzn("New York Plus 7 Time", "NYP7",
"New York Plus 7 Daylight Time", "NYP7D");
// With base UTC offset +2
int base_utc_offset_hr = 2;
time_duration utc_offset(base_utc_offset_hr,0,0);
// DST offset is +1 and starts and ends at 9am (2am + 7)
local_time::dst_adjustment_offsets adj_offsets(time_duration(1,0,0),
time_duration(9,0,0),
time_duration(9,0,0));
// DST starts the second Sunday of March and ends last Sunday of Nov
nth_kday_of_month start_rule(nth_kday_of_month::second, Sunday, Mar);
last_day_of_the_week_in_month end_rule(Sunday, Nov);
shared_ptr<dst_calc_rule> nyp7_rules(new nth_last_dst_rule(start_rule, end_rule));
// Construct the custom timezone
time_zone_ptr nyp7(new custom_time_zone(tzn, utc_offset, adj_offsets, nyp7_rules));
This can then be used to detect whether or not DST is in effect, and offset it into the source time
// Determine whether or not dst in effect for time 't'
ptime dst_start = nyp7->dst_local_start_time(year);
ptime dst_end = nyp7->dst_local_end_time(year);
bool dst_on = dst_start <= t && t < dst_end;
And subsequently the parsing and formatting can be done according to boost's user manual:
http://www.boost.org/doc/libs/1_51_0/doc/html/date_time/date_time_io.html

Related

How do I correctly transform the utc time displacement from a date time string?

I use Qt with Version 4.6.2 and try to transform a custom date string with UTC time displacement information into a QDateTime object.
QString format = "yyyy-MM-ddThh:mm:ss.zzz+hh:mm"
QDateTime dateTime = QDateTime::fromString("2017-10-18T08:30:02.000+01:00", format);
qDebug() << dateTime.toString(format);
The output is an empty string.
If I leave out the time displacement information in the format string and in the date string I get the date string as expected: 2017-10-18T08:30:02.000.
According to the Qt documentation of QDateTime::fromString there are no explicit format placeholders for the time displacement.
I also try the following
QDateTime dateTime = QDateTime::fromString("2017-10-18T08:30:02.000+01:00", Qt::ISODate); // ISO 8601
qDebug() << dateTime.toString(Qt::ISODate);
but the result is 2017-10-18T00:00:00.
So, how do I correctly transform the utc time displacement from a date time string?
In case you'd need to stay with Qt 4.6 you can manually look for the displacement and add the difference if present:
QString strDate = "2017-10-18T08:30:02.000+01:00";
QStringList tokens = strDate.split('+');
QString format = "yyyy-MM-ddThh:mm:ss.zzz"; // format without displacement
QDateTime dateTime = QDateTime::fromString(tokens[0], format);
if (tokens.count() == 2) { // input has displacement
QString format = "hh:mm";
int msecs = QTime::fromString(tokens[1], format).msecsSinceStartOfDay();
dateTime = dateTime.addMSecs(msecs);
}
qDebug() << dateTime.toString(format);

Where do calendar messages in PST files store appointment times and dates?

I am using the PST File Format SDK to try and extract some appointment item data from an Outlook PST export:
int main()
{
pst myfile(L"export.pst");
folder calendar = myfile.open_folder(L"Calendar");
for (folder::message_iterator msg = calendar.message_begin(); msg != calendar.message_end(); ++msg)
{
message m = *msg;
wstring subject = L"";
if (m.has_subject())
subject = m.get_subject();
wstring body = L"";
if (m.has_body())
body = m.get_body();
wstring htmlbody = L"";
if (m.has_html_body())
htmlbody = m.get_html_body();
size_t num_attachments = m.get_attachment_count();
size_t num_recipients = m.get_recipient_count();
property_bag bag = m.get_property_bag();
vector<prop_id> propertyList = bag.get_prop_list();
for (vector<prop_id>::iterator prop = propertyList.begin(); prop != propertyList.end(); ++prop)
{
if (bag.get_prop_type(*prop) == prop_type_systime)
FILETIME property = bag.read_prop<FILETIME>(*prop);
}
break; // Just try the first message for now.
}
return 0;
}
How does Outlook store appointment data? I mean, how can I get at the very least the appointment start time and duration (or end time)? I've been trying to scour the PST file format specification from Microsoft but I can't seem to find this information I need!
Edit: I can parse FILETIME objects as in the above code now, but the question is, how can I distinguish them to what time they are referring to? I mean, how can I tell if this is the time of the event date, or the end of the event date, etc.? They should have names to distinguish them, should they not? How do I get that using pstsdk?
These (and many more) properties are stored as named MAPI properties. Their tags will vary between different stores, so you cannot hardcode them. See the explanation of what named properties are on my web site: https://www.dimastr.com/redemption/utils.htm#named-props
Take a look at an existing appointment in OutlookSpy (I am its author) - click IMessage button.

c++ convert postgres timestamp without time zone to time_t

I'm connecting from c++ to postgreSQL using libpq library. I request and obtain the date (timestamp without time zone) from postgreSQL, but the result has an offset that I don't know how to fix.
Postgres table:
id date
integer timestamp without time zone
29996 2014-02-28 23:59:00
result in C++ code:
id: 29996, Date: Sat Mar 01 10:59:00 2014
You can see that the date has the offset. Below is the code that I'm using. Any help will be greatly appreciated
PGconn *m_connection;
PGresult *res;
string strConn = "dbname=test host=localhost user=username password=secret";
m_connection = PQconnectdb(strConn.c_str());
string query = "SELECT id, extract(epoch from date)::bigint ";
query += "FROM table_test ORDER BY id DESC LIMIT 1";
// send query
res = PQexecParams(m_connection, query.c_str(), 0, 0, 0, 0, 0, 0);
string id = PQgetvalue(res, 0, 0);
unsigned char *data = (unsigned char*)PQgetvalue( res, 0, 1 );
unsigned int length = PQgetlength( res, 0 , 1 );
time_t time = _atoi64( (char*)data );
PQclear(res);
std::cout << "id:"<< id << ", Date: " << ctime(&time) << "\n";
The issue is that ctime uses localtime, so that ends up in the offset.
If you want GMT, then you should use asctime(gmtime(&time)), which will give you a date/time without localtime influences.
ctime is the equivalent of asctime(localtime(&time))

ColdFusion - Get next scheduled task due to run

This thread was useful in finding out the next run-time for a scheduled task.
How do I find out the next run time for a Scheduled Task?
But, is there also a way to simply get the next scheduled task due to run?
If I can get the date and name of the next task due to run, I can plug that date into a jQuery countdown timer, which will display a countdown to the next scheduled task, something like:
TaskABC due to run in:
12 03 20
hrs min sec
. This is for an admin interface in case you're wondering how geeky can people get:-)
EDIT
I had the same thought as Bill. But was curious if there was another way.
I poked around and apparently the internal Scheduler class maintains a list of upcoming tasks. The list is private, but you can use the same reflection technique to access it. Interestingly the list also includes system tasks like the mail spooler, session/application trackers, watchers, etecetera. So you must iterate through it until you find a "scheduled task" ie CronTabEntry
Below is a very lightly tested function that seems to do the trick in CF9. (Note, includes the CreateTimeStruct function from http://www.cflib.org).
Rules:
Returns a structure containing the name and time remaining until the next task. If no tasks were found, result.task is an empty string.
Excludes paused tasks
Usage:
result = new TaskUtil().getNextTask();
WriteDump(result);
CFC
component {
public struct function getNextTask() {
// get list of upcoming tasks from factory (UNDOCUMENTED)
local.scheduler = createObject("java", "coldfusion.server.ServiceFactory").getSchedulerService();
local.taskField = local.scheduler.getClass().getDeclaredField("_tasks");
local.taskField.setAccessible( true );
local.taskList = local.taskField.get(local.scheduler);
// taskList contains system jobs too, so we must iterate
// through the tasks to find the next "scheduled task"
local.nextTask = "";
local.tasks = local.taskList.iterator();
while ( local.tasks.hasNext() ) {
local.currTask = local.tasks.next();
local.className = local.currTask.getRunnable().getClass().name;
// exit as soon as we find a scheduled task that is NOT paused
if (local.className eq "coldfusion.scheduling.CronTabEntry"
&& !local.currTask.getRunnable().paused) {
local.nextTask = local.currTask;
break;
}
}
// if we found a task, calculate how many days, hours, etcetera
// until its next run time
local.details = { task="", remaining={} };
if ( isObject(local.nextTask) ) {
local.secondsToGo = (local.nextTask.getWhen() - now().getTime()) / 1000;
local.details.task = local.nextTask.getRunnable().task;
local.details.remaining = createTimeStruct(local.secondsToGo);
local.details.nextDate = dateAdd("s", local.nextTask.getWhen() / 1000
, "January 1 1970 00:00:00" );
}
return local.details;
}
/**
* Abbreviated version of CreateTimeStruct by Dave Pomerance
* See http://www.cflib.org/index.cfm?event=page.udfbyid&udfid=421
*
* #param timespan The timespan to convert.
* #return Returns a structure.
* #author Dave Pomerance
* #version 1, January 7, 2002
*/
public struct function CreateTimeStruct(required numeric timespan) {
var timestruct = StructNew();
var mask = "s";
// only 4 allowed values for mask - if not one of those, return blank struct
if (ListFind("d,h,m,s", mask)) {
// compute seconds
if (mask eq "s") {
timestruct.s = (timespan mod 60) + (timespan - Int(timespan));
timespan = int(timespan/60);
mask = "m";
} else timestruct.s = 0;
// compute minutes
if (mask eq "m") {
timestruct.m = timespan mod 60;
timespan = int(timespan/60);
mask = "h";
} else timestruct.m = 0;
// compute hours, days
if (mask eq "h") {
timestruct.h = timespan mod 24;
timestruct.d = int(timespan/24);
} else {
timestruct.h = 0;
timestruct.d = timespan;
}
}
return timestruct;
}
}
My first thought is to iterate Leigh's getNextRunTime(string taskName) function over the collection of tasks. You can get an array of structs containing the details of all scheduled tasks using taskArray = createobject("java","coldfusion.server.ServiceFactory").getCronService().listAll();
The key in the struct containing the task name is "task". So you can extract all the task names as an array for example, run Leigh's function on each element and determine which one will run next.

Get the first day of week of a year (any programming language)

How can I get the first day of the week of any given year (day being 1 to 7, or weekday name)?
I tried to figure it out in JavaScript, but I accept any other language.
I need to select a year to later build the full calendar (I thought using HTML tables and JavaScript), and for that I need to know at least the first day of the selected year.
I haven't found a solution or a question specifically dealing with finding the first day of any given year such that you only need to pass 1995, 2007, 1891. So if it's a repeated question please point the solution.
Do you have at least an online chart or DHTML site where I can see any full calendar for any year visually in that way?
In Javascript you can use this:
getWeekDay = function (year) {
var d = new Date();
d.setFullYear(year,0,1);
return d.getDay()+1;
};
document.write(getWeekDay(2011));
Result is 1..7, as requested.
At this Wikipedia article, look for Sakamoto's algorithm.
Pretty easy with C# and .NET:
using System;
public class SomeClass
{
public static void Main()
{
DateTime dt = new DateTime(2000,1,1);
Console.WriteLine(dt.DayOfWeek);
dt = new DateTime(2010,1,1);
Console.WriteLine(dt.DayOfWeek);
}
}
Output:
Saturday
Friday
The Java version:
import java.util.Date;
import java.util.GregorianCalendar;
public class test3
{
public static void main (String[] args)
{
GregorianCalendar c = new GregorianCalendar(2000,1,1);
Date d = c.getTime();
System.out.println(d.getDay());
c = new GregorianCalendar(2010,1,1);
d = c.getTime();
System.out.println(d.getDay());
}
}
Output:
2
1
With .NET's BCL:
return new DateTime(year, 1, 1).DayOfWeek; // DayOfWeek enum value
In Noda Time:
return new LocalDate(year, 1, 1).IsoDayOfWeek; // IsoDayOfWeek enum value
In Java using the built-in classes:
Calendar calendar = Calendar.getInstance();
calendar.set(year, 1, 1);
return calendar.get(Calendar.DAY_OF_WEEK); // 1 (Sunday) - 7 (Saturday)
In Java using Joda Time:
return new LocalDate(year, 1, 1).getDayOfWeek(); // 1 (Monday) - 7 (Sunday)
This site http://5dspace-time.org/Calendar/Algorithm.html
has a good explanation on how to calculate it even with pencil-and-paper
Wikipedia explains it too