| 740 | // function of setting timezone in Windows is different from Linux. |
| 741 | #ifndef _MSC_VER |
| 742 | void testWriteTimestampWithTimezone(FileVersion fileVersion, const char* writerTimezone, |
| 743 | const char* readerTimezone, const std::string& tsStr, |
| 744 | int isDst = 0) { |
| 745 | char* tzBk = getenv("TZ"); // backup TZ env |
| 746 | |
| 747 | MemoryOutputStream memStream(DEFAULT_MEM_STREAM_SIZE); |
| 748 | MemoryPool* pool = getDefaultPool(); |
| 749 | std::unique_ptr<Type> type(Type::buildTypeFromString("struct<col1:timestamp>")); |
| 750 | |
| 751 | uint64_t stripeSize = 16 * 1024; |
| 752 | uint64_t compressionBlockSize = 1024; |
| 753 | uint64_t rowCount = 1; |
| 754 | uint64_t memoryBlockSize = 64; |
| 755 | |
| 756 | std::unique_ptr<Writer> writer = |
| 757 | createWriter(stripeSize, memoryBlockSize, compressionBlockSize, CompressionKind_ZLIB, *type, |
| 758 | pool, &memStream, fileVersion, 0, writerTimezone); |
| 759 | auto batch = writer->createRowBatch(rowCount); |
| 760 | auto& structBatch = dynamic_cast<StructVectorBatch&>(*batch); |
| 761 | auto& tsBatch = dynamic_cast<TimestampVectorBatch&>(*structBatch.fields[0]); |
| 762 | |
| 763 | // write timestamp in the writer timezone |
| 764 | setenv("TZ", writerTimezone, 1); |
| 765 | tzset(); |
| 766 | struct tm tm; |
| 767 | memset(&tm, 0, sizeof(struct tm)); |
| 768 | strptime(tsStr.c_str(), "%Y-%m-%d %H:%M:%S", &tm); |
| 769 | // mktime() does depend on external hint for daylight saving time |
| 770 | tm.tm_isdst = isDst; |
| 771 | tsBatch.data[0] = mktime(&tm); |
| 772 | tsBatch.nanoseconds[0] = 0; |
| 773 | structBatch.numElements = rowCount; |
| 774 | tsBatch.numElements = rowCount; |
| 775 | writer->add(*batch); |
| 776 | writer->close(); |
| 777 | |
| 778 | // read timestamp from the reader timezone |
| 779 | auto inStream = std::make_unique<MemoryInputStream>(memStream.getData(), memStream.getLength()); |
| 780 | std::unique_ptr<Reader> reader = createReader(pool, std::move(inStream)); |
| 781 | std::unique_ptr<RowReader> rowReader = createRowReader(reader.get(), readerTimezone); |
| 782 | EXPECT_EQ(true, rowReader->next(*batch)); |
| 783 | |
| 784 | // verify we get same wall clock in reader timezone |
| 785 | setenv("TZ", readerTimezone, 1); |
| 786 | tzset(); |
| 787 | memset(&tm, 0, sizeof(struct tm)); |
| 788 | time_t ttime = tsBatch.data[0]; |
| 789 | localtime_r(&ttime, &tm); |
| 790 | char buf[20]; |
| 791 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); |
| 792 | EXPECT_TRUE(strncmp(buf, tsStr.c_str(), tsStr.size()) == 0); |
| 793 | |
| 794 | // restore TZ env |
| 795 | if (tzBk) { |
| 796 | setenv("TZ", tzBk, 1); |
| 797 | tzset(); |
| 798 | } else { |
| 799 | unsetenv("TZ"); |
no test coverage detected