2010-04-09 41 views
11

Tôi đã viết một hàm trả lại giá trị time_t tương ứng với nửa đêm vào một ngày nhất định. Khi không có nửa đêm trong một ngày nhất định, nó sẽ trả về thời gian sớm nhất có sẵn; tình huống đó có thể xảy ra, ví dụ, khi Ai Cập vào thời gian tiết kiệm ánh sáng ban ngày. Năm nay, thời gian thay đổi có hiệu lực vào nửa đêm vào đêm ngày 29 tháng 4, vì vậy đồng hồ chạy trực tiếp từ 23:59 đến 01:00.Làm cách nào để chương trình Windows tạm thời thay đổi múi giờ của nó?

Bây giờ tôi đang viết các bài kiểm tra đơn vị cho chức năng này và một trong các bài kiểm tra sẽ nhân rộng kịch bản Ai Cập. Trong Unix, tôi có thể thực hiện nó như thế này:

putenv("TZ", "Egypt", true); 
tzset(); 

Sau khi làm điều đó, các cuộc gọi hơn nữa để localtime cư xử như thể họ đang ở Ai Cập thay vì Minnesota, và thử nghiệm của tôi vượt qua. Tuy nhiên, việc thiết lập biến môi trường không có bất kỳ hiệu ứng nào trên Windows. Tôi có thể làm gì để làm cho bài kiểm tra đơn vị nghĩ rằng nó ở một nơi khác mà không ảnh hưởng đến phần còn lại của các chương trình đang chạy trên hệ thống?

+1

whoosh .. có thể làm một cái móc để thay đổi hành vi của địa phương cho các bài kiểm tra của bạn thay thế? –

Trả lời

-1

Bạn đã thấy hàm API của hàm Win32 SetTimeZoneInformation chưa?

+0

Điều đó không thay đổi múi giờ cho toàn bộ hệ điều hành? Tôi muốn một cái gì đó giới hạn trong quá trình hiện tại (hoặc thread), phù hợp để sử dụng trong một bài kiểm tra đơn vị. –

+0

@Rob: Có, nó ảnh hưởng đến toàn bộ máy. Theo hiểu biết của tôi, không có phiên bản chuỗi địa phương. Tuy nhiên, nếu nó chỉ dành cho mục đích thử nghiệm đơn vị thì có thể vẫn ổn nếu bạn khôi phục múi giờ ban đầu trong phương pháp teardown thử nghiệm của bạn. – LBushkin

+7

Có lẽ chủ nhân của tôi có một triết lý khác về các bài kiểm tra đơn vị hơn bạn. Nếu một cái gì đó thay đổi cài đặt trên toàn hệ thống, nó sẽ không còn được phân loại như một bài kiểm tra đơn vị nữa và nó sẽ không chạy như một phần của quá trình xây dựng. Nhiều người có thể sử dụng cùng một máy chủ xây dựng và các thử nghiệm của họ không được can thiệp vào nhau. –

0

Tôi đã sử dụng setlocale(LC_ALL, "deu_aut") để chuyển cài đặt ngôn ngữ/quốc gia thành Áo - được khai báo trong locale.h. Đáng buồn là tôi đã không tìm thấy một chuỗi ngôn ngữ/quốc gia cho Ai Cập, nhưng có lẽ điều này mang lại cho bạn một gợi ý.

+1

Ngôn ngữ và quốc gia của Ai Cập là 'ar_EG' (cho * Arabic *). Nhưng những cài đặt đó không ảnh hưởng đến múi giờ. Chúng có thể ảnh hưởng đến định dạng được sử dụng để hiển thị thời gian hiện tại, nhưng điều đó không thực sự giống nhau. –

0

tôi có chính xác các yêu cầu tương tự:

-> một số quy trình phải được dán vào UTC và những người khác đối với một số múi giờ khác nhau từ hệ thống múi giờ của Windows

Sau nhiều tháng (gián đoạn) học mà tôi rơi để kết luận rằng trên Windows, bạn chỉ có thể đặt múi giờ hệ thống "UTC" hoặc "hiện tại". Vì vậy, chỉ sau đây có thể được thực hiện:

 
    - set TZ="UTC" 
    - unset TZ 
3

Sử dụng Isolation/Mocking khuôn khổ - là người duy nhất tôi biết lúc này là Isolator++ mà hiện đang trong phiên bản beta, tôi chắc chắn rằng bạn có thể nhận được một bản sao bằng cách hỏi cho một từ những người tốt của Typemock.

2

Check-out _putenv_s_tzset. Về lý thuyết, bạn sẽ có thể thiết lập các TZ biến môi trường cho quá trình của bạn với _putenv_s và sau đó sử dụng _tzset để thiết lập múi giờ địa phương thực tế cho quá trình của bạn với những gì TZ biến môi trường được thiết lập để.

Tôi biết rằng điều này hoạt động trên Linux với putenvtzset, và từ tài liệu của _putenv_s_tzset, dường như bạn sẽ có thể làm như vậy với họ trên Windows. Tôi đã không thực sự thử nó mặc dù.

+0

Nó không hoạt động trên Windows: chỉ UTC hoặc GMT đang hoạt động. – Alex

2

Vui lòng không gọi SetTimeZoneInformation - không có chủ đề hoặc khái niệm quy trình cụ thể của múi giờ trong Windows. Như những người khác nói, cách dễ nhất là giả lập mã múi giờ - với Pex/Mocks, bạn có thể thử nghiệm ngay cả các phương thức tĩnh, có nghĩa là bạn có thể móc mã Múi giờ chuẩn .NET để thay thế bằng mã thời gian của riêng bạn. Nếu bạn đang sử dụng C/C++, bạn chỉ cần kết nối mã để có thông tin TZ được mô phỏng.

0

Cài đặt móc nối cho GetTimeZoneInformation, ghi đè dữ liệu hệ thống với tùy chọn của riêng bạn.

1

Với VS 2008 (bản gốc C++) tôi đã có thể sửa đổi hành vi của localtime() bằng cách thay đổi biến số _timezone.

Tôi đồng ý, đây không phải là cách làm sạch, nhưng ít nhất đây có thể là giải pháp thay thế.

Tất nhiên, bạn cần tự làm toán để tìm số giây giữa UTC và múi giờ 'mới' của bạn.

Các vấn đề liên quan