Add date
This commit is contained in:
@ -12,7 +12,7 @@ namespace Tesses::CrossLang
|
||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
return dynDict->GetEnumerator(ls2);
|
||||
});
|
||||
fn->watch.push_back(dynDict);
|
||||
|
||||
@ -130,6 +130,7 @@ namespace Tesses::CrossLang
|
||||
if(std::holds_alternative<char>(args[0])) return "Char";
|
||||
if(std::holds_alternative<MethodInvoker>(args[0])) return "MethodInvoker";
|
||||
if(std::holds_alternative<std::string>(args[0])) return "String";
|
||||
|
||||
if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(args[0])) return "Path";
|
||||
if(std::holds_alternative<THeapObjectHolder>(args[0]))
|
||||
{
|
||||
@ -147,6 +148,8 @@ namespace Tesses::CrossLang
|
||||
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
|
||||
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
|
||||
auto svr = dynamic_cast<TServerHeapObject*>(obj);
|
||||
auto cse = dynamic_cast<CallStackEntry*>(obj);
|
||||
if(cse != nullptr) return "YieldedClosure";
|
||||
if(dynDict != nullptr) return "DynamicDictionary";
|
||||
if(dynList != nullptr) return "DynamicList";
|
||||
if(strm != nullptr)
|
||||
@ -300,12 +303,37 @@ namespace Tesses::CrossLang
|
||||
|
||||
}
|
||||
|
||||
static TObject YieldEnumerableFunc(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TClosure* closure;
|
||||
if(GetArgumentHeap(args,0,closure))
|
||||
{
|
||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for yield",{},[closure](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
return TYieldEnumerator::Create(ls2,closure);
|
||||
});
|
||||
fn->watch.push_back(closure);
|
||||
|
||||
enumerableItem->SetValue("GetEnumerator", fn);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
|
||||
{
|
||||
|
||||
env->permissions.canRegisterRoot=true;
|
||||
env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong);
|
||||
env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble);
|
||||
env->DeclareFunction(gc, "YieldEmumerable","Turn yield in function into enumerable",{"closure"},YieldEnumerableFunc);
|
||||
env->DeclareFunction(gc, "TypeOf","Get type of object",{"object"},TypeOf);
|
||||
env->DeclareFunction(gc, "TypeIsDefined","Get whether object is not null or undefined",{"object"},TypeIsDefined);
|
||||
env->DeclareFunction(gc, "TypeIsHeap","Get whether object is susceptible to garbage collection",{"object"},TypeIsHeap);
|
||||
@ -406,6 +434,7 @@ namespace Tesses::CrossLang
|
||||
RegisterCrypto(gc,env);
|
||||
RegisterOGC(gc, env);
|
||||
RegisterProcess(gc,env);
|
||||
RegisterTime(gc, env);
|
||||
|
||||
gc->RegisterEverything(env);
|
||||
|
||||
|
||||
194
src/runtime_methods/time.cpp
Normal file
194
src/runtime_methods/time.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
|
||||
#include "CrossLang.hpp"
|
||||
#include <unistd.h>
|
||||
#include "../HowardHinnant_date/date.h"
|
||||
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static int64_t ToLocalTime(int64_t local)
|
||||
{
|
||||
local -= timezone;
|
||||
if(daylight)
|
||||
{
|
||||
auto epoch = date::sys_days{date::January/1/1970};
|
||||
epoch += date::days(local/86400);
|
||||
|
||||
bool isDST = false;
|
||||
|
||||
date::year_month_day ymd(epoch);
|
||||
|
||||
auto month = (uint32_t)ymd.month();
|
||||
|
||||
if(month > 3 && month < 11)
|
||||
{
|
||||
isDST=true;
|
||||
}
|
||||
else if(month == 3)
|
||||
{
|
||||
auto day = (uint32_t)ymd.day();
|
||||
if(day > 14) isDST=true;
|
||||
else if(day >= 8 && day <= 14)
|
||||
{
|
||||
date::year_month_weekday ymw(epoch);
|
||||
auto dow=ymw.weekday().c_encoding();
|
||||
auto secondSunday = day - dow;
|
||||
if(secondSunday < 8) secondSunday+=7;
|
||||
|
||||
if(day > secondSunday) isDST=true;
|
||||
else if(day == secondSunday)
|
||||
{
|
||||
std::chrono::duration<int64_t> local_epoch_time(local);
|
||||
date::hh_mm_ss hms(local_epoch_time%86400);
|
||||
if(hms.hours().count() >= 2) isDST=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(month == 11)
|
||||
{
|
||||
auto day = (uint32_t)ymd.day();
|
||||
if(day >= 1 && day <= 7)
|
||||
{
|
||||
date::year_month_weekday ymw(epoch);
|
||||
auto dow=ymw.weekday().c_encoding();
|
||||
int32_t firstSunday = (int32_t)day - (int32_t)dow;
|
||||
if(firstSunday < 1) firstSunday+=7;
|
||||
|
||||
if(day < firstSunday) isDST=true;
|
||||
else if(day == firstSunday)
|
||||
{
|
||||
std::chrono::duration<int64_t> local_epoch_time(local);
|
||||
date::hh_mm_ss hms(local_epoch_time%86400);
|
||||
if(hms.hours().count() <=1) isDST=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isDST) local += 3600;
|
||||
}
|
||||
return local;
|
||||
}
|
||||
static TObject Time_getNow(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
return (time_t)t;
|
||||
}
|
||||
static TObject Time_Sleep(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t msec;
|
||||
if(GetArgument(args,0,msec))
|
||||
{
|
||||
if((msec % 100) == 0)
|
||||
{
|
||||
msec /= 100;
|
||||
for(int64_t i = 0; i < msec; i++)
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
else if((msec % 10) == 0)
|
||||
{
|
||||
msec /= 10;
|
||||
for(int64_t i = 0; i < msec; i++)
|
||||
{
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int64_t i = 0; i < msec; i++)
|
||||
{
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Time_LocalTime(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
//THIS code isn't the best but should work
|
||||
int64_t local;
|
||||
if(GetArgument(args,0,local))
|
||||
{
|
||||
local = ToLocalTime(local);
|
||||
|
||||
std::chrono::duration<int64_t> local_epoch_time(local);
|
||||
date::hh_mm_ss hms(local_epoch_time%86400);
|
||||
auto epoch = date::sys_days{date::January/1/1970};
|
||||
epoch += date::days(local/86400);
|
||||
|
||||
|
||||
|
||||
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
|
||||
|
||||
|
||||
// Convert sys_days to year_month_day
|
||||
date::year_month_day ymd = date::year_month_day(epoch);
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Hour",hms.hours().count());
|
||||
dict->SetValue("Minute",hms.minutes().count());
|
||||
dict->SetValue("Second",hms.seconds().count());
|
||||
|
||||
dict->SetValue("Day",(int64_t)(uint32_t)ymd.day());
|
||||
dict->SetValue("Month",(int64_t)(uint32_t)ymd.month());
|
||||
dict->SetValue("Year",(int64_t)(int32_t)ymd.year());
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Time_GMTTime(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t gmt;
|
||||
if(GetArgument(args,0,gmt))
|
||||
{
|
||||
std::chrono::duration<int64_t> epoch_time(gmt);
|
||||
date::hh_mm_ss hms(epoch_time%86400);
|
||||
auto epoch = date::sys_days{date::January/1/1970};
|
||||
epoch += date::days(gmt/86400);
|
||||
|
||||
|
||||
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
|
||||
|
||||
|
||||
// Convert sys_days to year_month_day
|
||||
date::year_month_day ymd = date::year_month_day(epoch);
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Hour",hms.hours().count());
|
||||
dict->SetValue("Minute",hms.minutes().count());
|
||||
dict->SetValue("Second",hms.seconds().count());
|
||||
|
||||
dict->SetValue("Day",(int64_t)(uint32_t)ymd.day());
|
||||
dict->SetValue("Month",(int64_t)(uint32_t)ymd.month());
|
||||
dict->SetValue("Year",(int64_t)(int32_t)ymd.year());
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterTime(GC* gc,TRootEnvironment* env)
|
||||
{
|
||||
|
||||
|
||||
|
||||
env->permissions.canRegisterTime=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "GetLocalTime", "Get local time from epoch value",{"epoch"},Time_LocalTime);
|
||||
dict->DeclareFunction(gc, "GetGMTTime","Get the GMT time from epoch value",{"epoch"},Time_GMTTime);
|
||||
dict->DeclareFunction(gc, "getNow","Get the time right now, returns C's time(NULL) return value",{},Time_getNow);
|
||||
dict->DeclareFunction(gc, "Sleep","Sleep for a specified amount of milliseconds (multiply seconds by 1000 to get milliseconds)", {"ms"},Time_Sleep);
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("Zone", (int64_t)-(timezone));
|
||||
dict->SetValue("SupportsDaylightSavings",(int64_t)daylight);
|
||||
env->DeclareVariable("Time", dict);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user