0. 前言
在上回我們說到,若是我們很常分享設定期效的檔案,逐個設定也是相當累人。
不只是檔案分享,假如我們今天有份重要檔案每日有個備份,我們通常只會留下 7 日的復原點,那此次我們會依靠檔案的建立日期進行比較,雖然降低點精確度,但可以自動將到期的檔案進行刪除。
1. 重點
2. 內容
2.1. 時間格式
在程式碼中的時間記錄,各位或許都聽過 Date 型態,然若沒有深入探索而不清楚其多種的樣式的,相對在處理與解析上就會有不同的麻煩點。
2.1.1. 常用格式
那在下方我們首先依靠 new Date() 取得現在時間,可以看到我們分別列出四種常用的紀錄方式。
function getDateFormat() {
let now = new Date();
// ISO 8601
console.log(now.toISOString()); // 2024-06-26T09:16:29.183Z
// Local Time
console.log(now.toString()); // Wed Jun 26 2024 17:16:29 GMT+0800 (GMT+08:00)
// RFC 7231
console.log(now.toUTCString()); // Wed, 26 Jun 2024 09:16:29 GMT
// Milliseconds
console.log(now.getTime()); // 1719393389183
}
ISO 8601 是國際標準日期和時間格式,其中的 T 區隔日期與時間,尾端的 Z 代表時區偏移。而 Local Time 則是生活中最常使用,區分時區之後的時間,可以看到尾端還會標示加減多少。RFC 7231 則主要用於 HTTP 其 Header 中攜帶的 HTTP-date 參數。
最後多介紹個毫秒數的表示法,它有致命的缺點是其開始自 UNIX 時間(1970),並且在長遠的未來數字會用完,但由於其計時單位極精細的因素,常用來判斷程式執行時長。
2.1.2. 時間細節
那在同樣都是 Date 格式下,可以倚靠以下方法快速取得指定數值。
function getDateDetail()
{
// Year
console.log("Year:", now.getFullYear());
// Month (0-11, where 0 = January and 11 = December)
console.log("Month:", now.getMonth() + 1); // +1 because months are zero-indexed
// Day of the Month
console.log("Day of the Month:", now.getDate());
// Day of the Week (0-6, where 0 = Sunday and 6 = Saturday)
console.log("Day of the Week:", now.getDay());
// Hours (0-23)
console.log("Hours:", now.getHours());
// Minutes (0-59)
console.log("Minutes:", now.getMinutes());
// Seconds (0-59)
console.log("Seconds:", now.getSeconds());
// Milliseconds (0-999)
console.log("Milliseconds:", now.getMilliseconds());
// Timezone Offset in Minutes
console.log("Timezone Offset (in minutes):", now.getTimezoneOffset());
}
要注意是 “月份” 與 “星期幾” 是從 0 開始記錄,而時差也有些反常理,+8 時區回傳值是 -480 分鐘。
2.2. 檔案屬性
在 Drive 中點擊檔案後能在右側看到許多指標,而我們接著就要提取檔案的屬性。
// Get all attributes of file
function getFileAttribute() {
const FILE_ID = 'FILE_ID';
const file = DriveApp.getFileById(FILE_ID);
// Basic Attribute
const fileName = file.getName();
const fileSize = file.getSize();
const fileId = file.getId();
const fileUrl = file.getUrl();
const fileDescription = file.getDescription();
const fileType = file.getMimeType();
const fileCreatedDate = file.getDateCreated();
const fileLastUpdated = file.getLastUpdated();
const fileOwner = file.getOwner().getEmail();
const fileEditors = file.getEditors().map(function(editor) {
return editor.getEmail();
}).join(', ');
const fileViewers = file.getViewers().map(function(viewer) {
return viewer.getEmail();
}).join(', ');
console.log('File Name: ' + fileName);
console.log('File Size: ' + fileSize + ' bytes');
console.log(`File ID: ${fileId}`);
console.log('File URL: ' + fileUrl);
console.log('File Description: ' + fileDescription);
console.log('File Type: ' + fileType);
console.log('File Created Date: ' + fileCreatedDate);
console.log('File Last Updated: ' + fileLastUpdated);
console.log('File Owner: ' + fileOwner);
console.log('File Editors: ' + fileEditors);
console.log('File Viewers: ' + fileViewers);
// File download URL
const fileDownloadUrl = file.getDownloadUrl();
console.log(`File Download URL: ${fileDownloadUrl}`);
// An data intercahnge object
const fileBlob = file.getBlob();
console.log(`File BLOB: ${fileBlob.getBytes()}`);
}
其中的 getUrl 是獲取檔案在 Drive 的位置,而 getDownloadUrl 則是下載連結,但同理用戶需要至少 READ 權限才能夠下載檔案。
而 Blob 比較常用於資料傳輸的過程,主要是給機器閱覽而非人類能快速理解的資訊,通常比較少用到。
2.3. 日期比對
我們進入到今日的議題,假設我們準備一個資料夾安置檔案的每日備份,以 7 日座基底進行測試 。
那由於時間的特性,為方便計算我設為 00:00.000 的情況,另外需要判定時間長過 days * 24 hr * 60 min * 60 sec * 1000 milli-sec 。後續可以看到一系列操作並透過 sorting 檔案時間,避免迴圈做無謂的檢查。
// - Scan childs in the target folder
// -- Sort all childs by date created
// ---- Compare date created with date today if is |lifeTime| days ago
// ------ T
// -------- Delete the file
// ------ F
// -------- BREAK the loop for there's no more longer than max life-time
function scanLifeTime() {
let folderId = 'FOLDER_ID';
// Max lifetime in days
let lifeTime = 7 * (24 * 3600 * 1000);
console.warn('# RUN - scanLifeTime()');
try {
// Parent
let folder = DriveApp.getFolderById(folderId);
// Childs
let files = folder.getFiles();
// List to store file info
let fileList = [];
// Timestamp to check lifetime
let today = new Date().setHours(0, 0, 0, 0);
// Gather all files into an array
while (files.hasNext()) {
let file = files.next();
fileList.push({
file: file,
createdDate: file.getDateCreated()
});
}
console.warn(`@ Sorting Files by Time Created`);
// Sort files by their creation date
fileList.sort((a, b) => a.createdDate - b.createdDate);
console.warn(`@ Deleting Files over Lifetime`);
// Iterate over the sorted array and delete files over lifetime
for (let i = 0; i < fileList.length; i++) {
let fileInfo = fileList[i];
let createdDate = fileInfo.createdDate.setHours(0, 0, 0, 0);
console.log(today - createdDate)
if ((today - createdDate) >= lifeTime) {
console.log(`(ID: ${fileInfo.file.getId()}) File ${fileInfo.file.getName()} removed for over lifetime`);
// Move to trash can
fileInfo.file.setTrashed(true);
}
// BREAK loop for no more longer than lifetime
else { console.log(`No files older than lifetime`); break; }
}
} catch (error) { console.error(error); }
console.warn('# END - scanLifeTime()');
}
那前面提到我們需要針對每日進行檢查,就要另外設置 Trigger 的 Day Timer,可以選定個人偏好的時段。
3. 後話
到這邊我們已基本了解磁碟操作方式,並了解到常用的兩種定時 Trigger。 但各位應該覺得目前活用範圍偏少,這便要依靠 Google 編輯器進行擴增與資料保存。
在過後呢我們將進入到 Google Form 並結合其他服務,那我們下期再見囉 ~~
4. 參考
[1] Date — MDN Web Docs
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
[2] Class File — Official Doc
https://developers.google.com/apps-script/reference/drive/file
[3] Class Blob — Official Doc
https://developers.google.com/apps-script/reference/base/blob.html
5. 素材
[1] 圖片素材 by QuAn_
https://www.pixiv.net/users/6657532