diff --git a/.travis.yml b/.travis.yml index 07da7a3..975666a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,38 +1,27 @@ -sudo: false +os: + - linux + - windows + - osx -env: - - CXX=g++-4.8 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 +sudo: false language: node_js +# node version 'node' means the very latest point version node_js: - - "0.8" - - "0.10" - - "0.12" - - "1" - - "2" - - "3" - - "4" - - "5" - - "6" - - "7" + - "8" + - "10" + - "11" + - "node" install: - - PATH="`npm bin`:`npm bin -g`:$PATH" - # Node 0.8 comes with a too obsolete npm - - if [[ "`node --version`" =~ ^v0\.8\. ]]; then npm install -g npm@1.4.28 ; fi - # Install dependencies and build - npm install +# note, the original master branch using nan did not have a travis +# job on windows and when unit tested was found to have breaking +# tests. If these were fixed existing work arounds would be broken +# on windows. script: - # Output useful info for debugging - node --version - npm --version - # Run tests - - npm test + - if [[ "$TRAVIS_OS_NAME" != "windows" ]]; then npm test ; fi diff --git a/appveyor.yml b/appveyor.yml index 1f272e7..d317460 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,15 +7,10 @@ environment: # Test against these versions of Node.js and io.js matrix: # node.js - - nodejs_version: "0.10" - - nodejs_version: "0.12" - # io.js - - nodejs_version: "2" - - nodejs_version: "3.2" - - nodejs_version: "4" - - nodejs_version: "5" - - nodejs_version: "6" - - nodejs_version: "7" + - nodejs_version: "8" + - nodejs_version: "9" + - nodejs_version: "10" + - nodejs_version: "11" platform: - x86 diff --git a/binding.gyp b/binding.gyp index 0b42e4b..1c80226 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,30 +1,37 @@ { - 'targets': [ - { - 'target_name': 'time', - 'include_dirs': [ - ' -#include -#include - -#include "nan.h" - -using namespace node; -using namespace v8; - -class Time { - public: - static void Init(Handle target) { - Nan::HandleScope scope; - - // time(3) - Nan::SetMethod(target, "time", Time_); - - // tzset(3) - Nan::SetMethod(target, "tzset", Tzset); - - // localtime - Nan::SetMethod(target, "localtime", Localtime); - - // mktime - Nan::SetMethod(target, "mktime", Mktime); - } - - static NAN_METHOD(Time_) { - Nan::EscapableHandleScope scope; - info.GetReturnValue().Set(scope.Escape(Nan::New(time(NULL)))); - } - - static NAN_METHOD(Tzset) { - Nan::EscapableHandleScope scope; - - // Set up the timezone info from the current TZ environ variable - tzset(); - - // Set up a return object that will hold the results of the timezone change - Local obj = Nan::New(); - - // The 'tzname' char * [] gets put into a JS Array - int tznameLength = 2; - Local tznameArray = Nan::New( tznameLength ); -#if _MSC_VER >= 1900 - char szTzName[128]; - - for (int i = 0; i < tznameLength; i++) { - size_t strLength; - _get_tzname(&strLength, szTzName, 128, i); - Nan::Set(tznameArray, i, Nan::New(szTzName).ToLocalChecked()); - } - - Nan::Set(obj, Nan::New("tzname").ToLocalChecked(), tznameArray); - - // The 'timezone' long is the "seconds West of UTC" - long timezone; - _get_timezone(&timezone); - Nan::Set(obj, Nan::New("timezone").ToLocalChecked(), Nan::New(timezone)); - - // The 'daylight' int is obselete actually, but I'll include it here for - // curiosity's sake. See the "Notes" section of "man tzset" - int daylight; - _get_daylight(&daylight); - Nan::Set(obj, Nan::New("daylight").ToLocalChecked(), Nan::New(daylight)); -#else - for (int i=0; i < tznameLength; i++) { - Nan::Set(tznameArray, i, Nan::New(tzname[i]).ToLocalChecked()); - } - - Nan::Set(obj, Nan::New("tzname").ToLocalChecked(), tznameArray); - - // The 'timezone' long is the "seconds West of UTC" - Nan::Set(obj, Nan::New("timezone").ToLocalChecked(), Nan::New( timezone )); - - // The 'daylight' int is obselete actually, but I'll include it here for - // curiosity's sake. See the "Notes" section of "man tzset" - Nan::Set(obj, Nan::New("daylight").ToLocalChecked(), Nan::New( daylight )); -#endif - info.GetReturnValue().Set(scope.Escape(obj)); - } - - static NAN_METHOD(Localtime) { - Nan::EscapableHandleScope scope; - - // Construct the 'tm' struct - time_t rawtime = static_cast(info[0]->IntegerValue()); - struct tm *timeinfo = localtime( &rawtime ); - - // Create the return "Object" - Local obj = Nan::New(); - - if (timeinfo) { - Nan::Set(obj, Nan::New("seconds").ToLocalChecked(), Nan::New(timeinfo->tm_sec) ); - Nan::Set(obj, Nan::New("minutes").ToLocalChecked(), Nan::New(timeinfo->tm_min) ); - Nan::Set(obj, Nan::New("hours").ToLocalChecked(), Nan::New(timeinfo->tm_hour) ); - Nan::Set(obj, Nan::New("dayOfMonth").ToLocalChecked(), Nan::New(timeinfo->tm_mday) ); - Nan::Set(obj, Nan::New("month").ToLocalChecked(), Nan::New(timeinfo->tm_mon) ); - Nan::Set(obj, Nan::New("year").ToLocalChecked(), Nan::New(timeinfo->tm_year) ); - Nan::Set(obj, Nan::New("dayOfWeek").ToLocalChecked(), Nan::New(timeinfo->tm_wday) ); - Nan::Set(obj, Nan::New("dayOfYear").ToLocalChecked(), Nan::New(timeinfo->tm_yday) ); - Nan::Set(obj, Nan::New("isDaylightSavings").ToLocalChecked(), Nan::New(timeinfo->tm_isdst > 0) ); - -#if defined HAVE_TM_GMTOFF - // Only available with glibc's "tm" struct. Most Linuxes, Mac OS X... - Nan::Set(obj, Nan::New("gmtOffset").ToLocalChecked(), Nan::New(timeinfo->tm_gmtoff) ); - Nan::Set(obj, Nan::New("timezone").ToLocalChecked(), Nan::New(timeinfo->tm_zone).ToLocalChecked() ); - -#elif defined HAVE_TIMEZONE - // Compatibility for Cygwin, Solaris, probably others... - long scd; - if (timeinfo->tm_isdst > 0) { - #ifdef HAVE_ALTZONE - scd = -altzone; - #else - scd = -timezone + 3600; - #endif // HAVE_ALTZONE - } else { - scd = -timezone; - } - Nan::Set(obj, Nan::New("gmtOffset").ToLocalChecked(), Nan::New(scd)); - Nan::Set(obj, Nan::New("timezone").ToLocalChecked(), Nan::New(tzname[timeinfo->tm_isdst])); -#endif // HAVE_TM_GMTOFF - } else { - Nan::Set(obj, Nan::New("invalid").ToLocalChecked(), Nan::New(true)); - } - - info.GetReturnValue().Set(scope.Escape(obj)); - } - - static NAN_METHOD(Mktime) { - Nan::EscapableHandleScope scope; - - if (info.Length() < 1) { - return Nan::ThrowTypeError("localtime() Object expected"); - } - - Local arg = info[0].As(); - - struct tm tmstr; - tmstr.tm_sec = Nan::Get(arg, Nan::New("seconds").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_min = Nan::Get(arg, Nan::New("minutes").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_hour = Nan::Get(arg, Nan::New("hours").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_mday = Nan::Get(arg, Nan::New("dayOfMonth").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_mon = Nan::Get(arg, Nan::New("month").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_year = Nan::Get(arg, Nan::New("year").ToLocalChecked()).ToLocalChecked()->Int32Value(); - tmstr.tm_isdst = Nan::Get(arg, Nan::New("isDaylightSavings").ToLocalChecked()).ToLocalChecked()->Int32Value(); - // tm_wday and tm_yday are ignored for input, but properly set after 'mktime' is called - - info.GetReturnValue().Set(scope.Escape(Nan::New(static_cast(mktime( &tmstr ))))); - } - -}; - -extern "C" { - static void init (Handle target) { - Time::Init(target); - } - NODE_MODULE(time, init) -} diff --git a/src/time_napi.cc b/src/time_napi.cc new file mode 100644 index 0000000..d2f2def --- /dev/null +++ b/src/time_napi.cc @@ -0,0 +1,162 @@ +#include +#include "time_napi.h" +#include + +Napi::FunctionReference Time::constructor; + +Napi::Object Time::Init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + + Napi::Function func = DefineClass(env, "Time", { + InstanceMethod("tzset", &Time::tzset), + InstanceMethod("localtime", &Time::localtime), + InstanceMethod("mktime", &Time::mktime), + }); + + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); + + exports.Set("Time", func); + return exports; +} + +Time::Time(const Napi::CallbackInfo &info) : Napi::ObjectWrap