Skip to content

Commit 0bf28f7

Browse files
committed
add forceLocalTime option to override default of UTC times in archives.
1 parent baf3653 commit 0bf28f7

5 files changed

Lines changed: 37 additions & 23 deletions

File tree

lib/archivers/zip/util.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
*/
88
var util = module.exports = {};
99

10-
util.dateToDos = function(d) {
11-
var year = d.getUTCFullYear();
10+
util.dateToDos = function(d, forceLocalTime) {
11+
forceLocalTime = forceLocalTime || false;
12+
13+
var year = forceLocalTime ? d.getFullYear() : d.getUTCFullYear();
1214

1315
if (year < 1980) {
1416
return 2162688; // 1980-1-1 00:00:00
@@ -18,26 +20,19 @@ util.dateToDos = function(d) {
1820

1921
var val = {
2022
year: year,
21-
month: d.getUTCMonth(),
22-
date: d.getUTCDate(),
23-
hours: d.getUTCHours(),
24-
minutes: d.getUTCMinutes(),
25-
seconds: d.getUTCSeconds()
23+
month: forceLocalTime ? d.getMonth() : d.getUTCMonth(),
24+
date: forceLocalTime ? d.getDate() : d.getUTCDate(),
25+
hours: forceLocalTime ? d.getHours() : d.getUTCHours(),
26+
minutes: forceLocalTime ? d.getMinutes() : d.getUTCMinutes(),
27+
seconds: forceLocalTime ? d.getSeconds() : d.getUTCSeconds()
2628
};
2729

2830
return ((val.year - 1980) << 25) | ((val.month + 1) << 21) | (val.date << 16) |
2931
(val.hours << 11) | (val.minutes << 5) | (val.seconds / 2);
3032
};
3133

3234
util.dosToDate = function(dos) {
33-
return new Date(
34-
((dos >> 25) & 0x7f) + 1980,
35-
((dos >> 21) & 0x0f) - 1,
36-
(dos >> 16) & 0x1f,
37-
(dos >> 11) & 0x1f,
38-
(dos >> 5) & 0x3f,
39-
(dos & 0x1f) << 1
40-
);
35+
return new Date(((dos >> 25) & 0x7f) + 1980, ((dos >> 21) & 0x0f) - 1, (dos >> 16) & 0x1f, (dos >> 11) & 0x1f, (dos >> 5) & 0x3f, (dos & 0x1f) << 1);
4136
};
4237

4338
util.fromDosTime = function(buf) {

lib/archivers/zip/zip-archive-entry.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,12 @@ ZipArchiveEntry.prototype.setSize = function(size) {
191191
this.size = size;
192192
};
193193

194-
ZipArchiveEntry.prototype.setTime = function(time) {
194+
ZipArchiveEntry.prototype.setTime = function(time, forceLocalTime) {
195195
if (!(time instanceof Date)) {
196196
throw new Error('invalid entry time');
197197
}
198198

199-
this.time = zipUtil.dateToDos(time);
199+
this.time = zipUtil.dateToDos(time, forceLocalTime);
200200
};
201201

202202
ZipArchiveEntry.prototype.setUnixMode = function(mode) {

lib/archivers/zip/zip-archive-output-stream.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ var ZipArchiveOutputStream = module.exports = function(options) {
3636
finish: false,
3737
finished: false,
3838
processing: false,
39-
forceZip64: options.forceZip64
39+
forceZip64: options.forceZip64,
40+
forceLocalTime: options.forceLocalTime
4041
};
4142
};
4243

@@ -114,6 +115,7 @@ ZipArchiveOutputStream.prototype._defaults = function(o) {
114115
}
115116

116117
o.forceZip64 = !!o.forceZip64;
118+
o.forceLocalTime = !!o.forceLocalTime;
117119

118120
return o;
119121
};
@@ -150,7 +152,7 @@ ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
150152
}
151153

152154
if (ae.getTime() === -1) {
153-
ae.setTime(new Date());
155+
ae.setTime(new Date(), this._archive.forceLocalTime);
154156
}
155157

156158
ae._offsets = {
@@ -163,8 +165,8 @@ ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
163165
ZipArchiveOutputStream.prototype._smartStream = function(ae, callback) {
164166
var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
165167
var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();
168+
var error = null;
166169

167-
var error = null
168170
function handleStuff() {
169171
ae.setCrc(process.digest());
170172
ae.setSize(process.size());

test/zip-archive-entry.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ var ZipArchiveEntry = commons.ZipArchiveEntry;
66
var GeneralPurposeBit = require('../lib/archivers/zip/general-purpose-bit');
77

88
var entry;
9-
var testDate = new Date('Jan 03 2013 14:26:38 GMT');
9+
// Jan 03 2013 14:26:38 GMT
10+
var testDate = new Date(Date.UTC(2013, 0, 3, 14, 26, 38, 0));
1011

1112
describe('ZipArchiveEntry', function() {
1213

@@ -257,9 +258,9 @@ describe('ZipArchiveEntry', function() {
257258
});
258259

259260
describe('#setTime', function() {
260-
it.skip('should set internal variable', function() {
261+
it('should set internal variable', function() {
261262
entry.setTime(testDate);
262-
assert.propertyVal(entry, 'time', 1109607251);
263+
assert.propertyVal(entry, 'time', 1109619539);
263264
});
264265
});
265266

test/zip-archive-output-stream.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ describe('ZipArchiveOutputStream', function() {
107107
});
108108
});
109109

110+
it('should force UTC', function(done) {
111+
var archive = new ZipArchiveOutputStream({
112+
forceUTC: true
113+
});
114+
var testStream = new WriteHashStream('tmp/zip-stream64.zip');
115+
var entry = new ZipArchiveEntry('stream.txt');
116+
117+
testStream.on('close', function() {
118+
done();
119+
});
120+
121+
archive.pipe(testStream);
122+
123+
archive.entry(entry, fs.createReadStream('test/fixtures/test.txt')).finish();
124+
});
125+
110126
it('should force ZIP64', function(done) {
111127
var archive = new ZipArchiveOutputStream({
112128
forceZip64: true

0 commit comments

Comments
 (0)