Skip to content

Commit f09070a

Browse files
committed
Merge branch 'master' into reinvent-wheel
2 parents 6d83aa8 + 579aa7e commit f09070a

File tree

98 files changed

+6285
-5839
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+6285
-5839
lines changed

.eslintrc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"camelcase": "off",
3434
"@typescript-eslint/camelcase": "off"
3535

36-
}
36+
}
3737
}, {
3838
"files": ["**/test/**/*.js"],
3939
"rules": {
@@ -42,7 +42,7 @@
4242
"comments": 200,
4343
"ignoreTrailingComments": true
4444
}]
45-
}
45+
}
4646
}, {
4747
"files": ["**/*.md"],
4848
"rules": {
@@ -64,6 +64,7 @@
6464
"ignoreTrailingComments": true
6565
}],
6666
"@typescript-eslint/camelcase": "off",
67+
"linebreak-style": ["error","unix"],
6768
"camelcase": "off",
6869
"no-const-assign": "error",
6970
"no-this-before-super": "error",

.gitattributes

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.ipynb linguist-documentation
22
docs/* linguist-documentation
33
python/perspective/notebooks/* linguist-documentation
4-
python/perspective/docs/* linguist-documentation
4+
python/perspective/docs/* linguist-documentation
5+
*.js text eol=lf

azure-pipelines.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,11 @@ jobs:
231231
env:
232232
# Set `BOOST_ROOT` manually, as `BOOST_ROOT` is removed in the VM:
233233
# https://github.com/actions/virtual-environments/issues/687
234-
BOOST_ROOT: "C:/hostedtoolcache/windows/Boost/1.69.0/"
235-
BOOST_INCLUDEDIR: "C:/hostedtoolcache/windows/Boost/1.69.0/include"
236-
BOOST_LIBRARYDIR: "C:/hostedtoolcache/windows/Boost/1.69.0/libs"
234+
# 06/18/2020 - seems like boost got moved to `x86_64` inside
235+
# the boost folder, which broke builds for a bit.
236+
BOOST_ROOT: "C:/hostedtoolcache/windows/Boost/1.69.0/x86_64/"
237+
BOOST_INCLUDEDIR: "C:/hostedtoolcache/windows/Boost/1.69.0/x86_64/include"
238+
BOOST_LIBRARYDIR: "C:/hostedtoolcache/windows/Boost/1.69.0/x86_64/libs"
237239

238240

239241
- job: 'MacOS_Mojave'

cpp/perspective/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,26 @@ function (psp_build_dep name cmake_file)
4545
message(WARNING "${Cyan}Dependency found - not rebuilding - ${CMAKE_BINARY_DIR}/${name}-build${ColorReset}")
4646
else()
4747
configure_file(${cmake_file} ${name}-download/CMakeLists.txt)
48+
4849
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
4950
RESULT_VARIABLE result
5051
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${name}-download )
52+
5153
if(result)
5254
message(FATAL_ERROR "CMake step for ${name} failed: ${result}")
5355
endif()
56+
5457
execute_process(COMMAND ${CMAKE_COMMAND} --build .
5558
RESULT_VARIABLE result
5659
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${name}-download )
60+
5761
if(result)
5862
message(FATAL_ERROR "Build step for ${name} failed: ${result}")
5963
endif()
6064
endif()
6165

6266
if(${name} STREQUAL arrow)
67+
# Overwrite arrow's CMakeLists with our custom, minimal one
6368
configure_file(${PSP_CMAKE_MODULE_PATH}/arrow/CMakeLists.txt ${CMAKE_BINARY_DIR}/arrow-src/cpp/ COPYONLY)
6469
configure_file(${PSP_CMAKE_MODULE_PATH}/arrow/config.h ${CMAKE_BINARY_DIR}/arrow-src/cpp/src/arrow/util/ COPYONLY)
6570
add_subdirectory(${CMAKE_BINARY_DIR}/arrow-src/cpp/
@@ -297,7 +302,7 @@ elseif(PSP_CPP_BUILD OR PSP_PYTHON_BUILD)
297302
# must be set to `NEW` to allow BOOST_ROOT to be defined by env var
298303
cmake_policy(SET CMP0074 NEW)
299304

300-
if(DEFINED(ENV{BOOST_ROOT}))
305+
if(DEFINED (ENV{BOOST_ROOT}))
301306
set(Boost_NO_BOOST_CMAKE TRUE)
302307

303308
message(WARNING "${Cyan}BOOST_ROOT: $ENV{BOOST_ROOT} ${ColorReset}")
@@ -635,6 +640,7 @@ elseif(PSP_CPP_BUILD OR PSP_PYTHON_BUILD)
635640
endif()
636641

637642
target_link_libraries(psp tbb)
643+
638644
target_link_libraries(binding tbb)
639645

640646
target_link_libraries(binding psp)

cpp/perspective/src/cpp/computed.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ t_computed_column::computed_functions = {
10431043
{"category", "FunctionTokenType"},
10441044
{"num_params", "1"},
10451045
{"format_function", "x => `hour_of_day(${x})`"},
1046-
{"help", "Returns the hour of day (0-23) in UTC for the datetime column."},
1046+
{"help", "Returns the hour of day (0-23) for the datetime column."},
10471047
{"signature", "hour_of_day(x: Datetime): Number"}
10481048
}},
10491049
{"day_of_week", {
@@ -1056,7 +1056,7 @@ t_computed_column::computed_functions = {
10561056
{"category", "FunctionTokenType"},
10571057
{"num_params", "1"},
10581058
{"format_function", "x => `day_of_week(${x})`"},
1059-
{"help", "Returns the day of week in UTC for the datetime column."},
1059+
{"help", "Returns the day of week for the datetime column."},
10601060
{"signature", "day_of_week(x: Datetime): String"}
10611061
}},
10621062
{"month_of_year", {
@@ -1069,7 +1069,7 @@ t_computed_column::computed_functions = {
10691069
{"category", "FunctionTokenType"},
10701070
{"num_params", "1"},
10711071
{"format_function", "x => `month_of_year(${x})`"},
1072-
{"help", "Returns the month of year in UTC for the datetime column."},
1072+
{"help", "Returns the month of year for the datetime column."},
10731073
{"signature", "month_of_year(x: Datetime): String"}
10741074
}},
10751075
{"second_bucket", {

cpp/perspective/src/cpp/computed_function.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,13 @@ t_tscalar hour_of_day<DTYPE_TIME>(t_tscalar x) {
527527
// Convert the timestamp to a `sys_time` (alias for `time_point`)
528528
date::sys_time<std::chrono::milliseconds> ts(timestamp);
529529

530-
// Create a copy of the timestamp with day precision
531-
date::sys_days days = date::floor<date::days>(ts);
532-
533-
// Subtract the day-precision `time_point` from the datetime-precision one
534-
auto time_of_day = date::make_time(ts - days);
530+
// Use localtime so that the hour of day is consistent with all output
531+
// datetimes, which are in local time
532+
std::time_t temp = std::chrono::system_clock::to_time_t(ts);
533+
std::tm* t = std::localtime(&temp);
535534

536-
// Get the hour from the resulting `time_point`
537-
rval.set(static_cast<std::int64_t>(time_of_day.hours().count()));
535+
// Get the hour from the resulting `std::tm`
536+
rval.set(static_cast<std::int64_t>(t->tm_hour));
538537
return rval;
539538
}
540539

@@ -831,14 +830,14 @@ void day_of_week<DTYPE_TIME>(
831830
// Convert the timestamp to a `sys_time` (alias for `time_point`)
832831
date::sys_time<std::chrono::milliseconds> ts(timestamp);
833832

834-
// Create a copy of the timestamp with day precision
835-
auto days = date::floor<date::days>(ts);
836-
837-
// Find the weekday and write it to the output column
838-
auto weekday = date::year_month_weekday(days).weekday_indexed().weekday();
833+
// Use localtime so that the hour of day is consistent with all output
834+
// datetimes, which are in local time
835+
std::time_t temp = std::chrono::system_clock::to_time_t(ts);
836+
std::tm* t = std::localtime(&temp);
839837

838+
// Get the weekday from the resulting `std::tm`
840839
output_column->set_nth(
841-
idx, days_of_week[(weekday - date::Sunday).count()]);
840+
idx, days_of_week[t->tm_wday]);
842841
}
843842

844843
template <>
@@ -871,18 +870,16 @@ void month_of_year<DTYPE_TIME>(
871870
// Convert the timestamp to a `sys_time` (alias for `time_point`)
872871
date::sys_time<std::chrono::milliseconds> ts(timestamp);
873872

874-
// Create a copy of the timestamp with day precision
875-
auto days = date::floor<date::days>(ts);
876-
877-
// Cast the `time_point` to contain year/month/day
878-
auto ymd = date::year_month_day(days);
873+
// Use localtime so that the hour of day is consistent with all output
874+
// datetimes, which are in local time
875+
std::time_t temp = std::chrono::system_clock::to_time_t(ts);
876+
std::tm* t = std::localtime(&temp);
879877

880-
// Get the month as an integer from 0 to 11
881-
auto month = (ymd.month() - date::January).count();
878+
// Get the month from the resulting `std::tm`
879+
auto month = t->tm_mon;
882880

883881
// Get the month string and write into the output column
884-
std::string month_of_year = months_of_year[month];
885-
output_column->set_nth(idx, month_of_year);
882+
output_column->set_nth(idx, months_of_year[month]);
886883
}
887884

888885
} // end namespace computed_function

cpp/perspective/src/cpp/scalar.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,9 +679,23 @@ t_tscalar::to_string(bool for_expr) const {
679679
return ss.str();
680680
} break;
681681
case DTYPE_TIME: {
682+
// Convert a millisecond UTC timestamp to a formatted datestring in
683+
// local time, as all datetimes exported to the user happens in
684+
// local time and not UTC.
682685
std::chrono::milliseconds timestamp(to_int64());
683686
date::sys_time<std::chrono::milliseconds> ts(timestamp);
684-
ss << date::format("%Y-%m-%d %H:%M:%S", ts);
687+
std::time_t temp = std::chrono::system_clock::to_time_t(ts);
688+
std::tm* t = std::localtime(&temp);
689+
690+
// use a mix of std::put_time and date::format to properly
691+
// represent datetimes to millisecond precision
692+
ss << std::put_time(t, "%Y-%m-%d %H:%M:"); // ymd h:m
693+
694+
// TODO: we currently can't print out millisecond precision, but
695+
// we need to.
696+
ss << date::format("%S", ts); // represent second and millisecond
697+
ss << std::put_time(t, " %Z"); // timezone
698+
685699
return ss.str();
686700
} break;
687701
case DTYPE_STR: {

cpp/perspective/src/include/perspective/base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <fstream>
3131
#include <boost/unordered_map.hpp>
3232
#include <perspective/portable.h>
33+
#include <stdlib.h>
3334

3435
namespace perspective {
3536

docs/i18n/en.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,6 @@
3535
"node_modules/react/README": {
3636
"title": "node_modules/react/README"
3737
},
38-
"obj/perspective-python": {
39-
"title": "perspective-python API"
40-
},
41-
"obj/perspective-viewer": {
42-
"title": "perspective-viewer API"
43-
},
44-
"obj/perspective": {
45-
"title": "perspective API"
46-
},
4738
"README": {
4839
"title": "README"
4940
}

docs/md/python.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,18 @@ two methods into your object:
159159

160160
#### Time Zone Handling
161161

162-
When passing in `datetime` objects, Perspective checks the `tzinfo` attribute
163-
to see if a time zone is set. For more details, see this in-depth [explanation](https://github.com/finos/perspective/pull/867)
164-
of `perspective-python` semantics around time zone handling.
162+
Columns with the `datetime` type are stored internally as UTC timestamps in milliseconds since epoch (Unix Time),
163+
and are serialized to the user as `datetime.datetime` objects in _local time_ according to the Python runtime.
165164

166-
##### Naive Datetimes
165+
Both ["naive" and "aware" datetimes](https://docs.python.org/3/library/datetime.html#aware-and-naive-objects) will be
166+
serialized to local time by Perspective, with the conversion determined by the `tzinfo` attribute:
167167

168-
Objects with an unset `tzinfo` attribute (naive datetimes) are treated as _local time_, and do not undergo any time zone conversion.
168+
- "Naive" datetimes are assumed to be already in local time and are serialized as-is.
169+
- "Aware" datetimes will be converted to UTC from their original timezone, and then converted to local time
170+
from UTC.
169171

170-
##### Aware Datetimes
171-
172-
Objects with the `tzinfo` attribute set (aware datetimes) will be _converted into UTC_ before being stored in
173-
Perspective, and they will be _serialized as local time_.
172+
This behavior is consistent with Perspective's behavior in Javascript. For more details, see this
173+
in-depth [explanation](https://github.com/finos/perspective/pull/867) of `perspective-python` semantics around time zone handling.
174174

175175
##### Pandas Timestamps
176176

0 commit comments

Comments
 (0)