본문 바로가기
카테고리 없음

App Script - 선택한 시간셀의 배색을 서울 기준 낮과 밤에 맞게 꾸미기

by redcubes 2025. 3. 9.
function setSkyColorForSelectedCells() {
  try {
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var selection = sheet.getActiveRange();
    var values = selection.getValues();
    
    var today = new Date();
    var latitude = 37.5665; // 서울 기준
    var longitude = 126.9780;

    var twilightTimes = getTwilightTimes(latitude, longitude, today);
    
    Logger.log("🌅 시민박명 시작 (KST): " + twilightTimes.civilDawn + "시");
    Logger.log("🌊 항해박명 시작 (KST): " + twilightTimes.nauticalDawn + "시");
    Logger.log("🌙 천문박명 시작 (KST): " + twilightTimes.astroDawn + "시");
    Logger.log("☀️ 일출 (KST): " + twilightTimes.sunrise + "시");
    Logger.log("🌇 일몰 (KST): " + twilightTimes.sunset + "시");
    
    var backgroundColors = [];
    var fontColors = [];

    for (var i = 0; i < values.length; i++) {
      var rowColors = [];
      var rowFontColors = [];
      
      for (var j = 0; j < values[i].length; j++) {
        var timeCell = values[i][j];

        if (timeCell instanceof Date) {
          var cellTime = new Date(timeCell).getHours() + new Date(timeCell).getMinutes() / 60;
          Logger.log("⏰ 셀 시간: " + cellTime + "시");

          var bgColor = getSkyColor(cellTime, twilightTimes);
          var fontColor = getContrastingTextColor(bgColor);
          
          rowColors.push(bgColor);
          rowFontColors.push(fontColor);
        } else {
          rowColors.push("#ffffff"); 
          rowFontColors.push("#000000"); 
        }
      }

      backgroundColors.push(rowColors);
      fontColors.push(rowFontColors);
    }

    Logger.log("✅ 최종 적용된 색상 개수: " + backgroundColors.length);
    selection.setBackgrounds(backgroundColors);
    selection.setFontColors(fontColors);

  } catch (error) {
    Logger.log("🚨 오류 발생: " + error.toString());
  }
}

// 🌅 천문/항해/시민박명 및 일출/일몰 시간 가져오기 (KST 변환 정확하게 수행)
function getTwilightTimes(lat, lon, date) {
  var formattedDate = Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy-MM-dd");
  var url = `https://api.sunrise-sunset.org/json?lat=${lat}&lng=${lon}&date=${formattedDate}&formatted=0`;

  var response = UrlFetchApp.fetch(url);
  var data = JSON.parse(response.getContentText());

  function convertToKST(isoString) {
    var date = new Date(isoString);
    if (isNaN(date)) {
      Logger.log("🚨 시간 변환 오류: " + isoString);
      return NaN;
    }
    date.setHours(date.getUTCHours() + 9); // UTC → KST 변환
    return date.getHours() + date.getMinutes() / 60;
  }

  return {
    astroDawn: convertToKST(data.results.astronomical_twilight_begin),
    nauticalDawn: convertToKST(data.results.nautical_twilight_begin),
    civilDawn: convertToKST(data.results.civil_twilight_begin),
    sunrise: convertToKST(data.results.sunrise),
    sunset: convertToKST(data.results.sunset),
    civilDusk: convertToKST(data.results.civil_twilight_end),
    nauticalDusk: convertToKST(data.results.nautical_twilight_end),
    astroDusk: convertToKST(data.results.astronomical_twilight_end)
  };
}

// 🌌 시간에 따른 하늘 색상 설정 (박명 고려)
function getSkyColor(time, times) {
  var colors = {
    night: "#000033",      // 완전한 밤 (천문박명 이전)
    astroTwilight: "#111144", // 천문박명 (매우 어두운 파랑)
    nauticalTwilight: "#222266", // 항해박명 (짙은 파랑)
    civilTwilight: "#333366", // 시민박명 (어두운 파랑)
    morning: "#6699FF",    // 아침 (밝은 하늘색)
    noon: "#BBDEFB",       // 낮 (연한 하늘색)
    afternoon: "#6699FF",  // 오후 (밝은 하늘색)
    evening: "#333366",    // 저녁 (어두운 파랑)
    nauticalDusk: "#222266", // 항해박명 (짙은 파랑)
    astroDusk: "#111144", // 천문박명 (매우 어두운 파랑)
    nightAgain: "#000033"  // 다시 밤
  };

  if (time < times.astroDawn) return colors.night;
  if (time < times.nauticalDawn) return colors.astroTwilight;
  if (time < times.civilDawn) return colors.nauticalTwilight;
  if (time < times.sunrise) return colors.civilTwilight;
  if (time < times.sunrise + 2) return colors.morning;
  if (time < times.sunset - 2) return colors.noon;
  if (time < times.sunset) return colors.afternoon;
  if (time < times.civilDusk) return colors.evening;
  if (time < times.nauticalDusk) return colors.nauticalDusk;
  if (time < times.astroDusk) return colors.astroDusk;
  return colors.nightAgain;
}

// 🖋 배경색에 따른 대비가 높은 글자색 반환
function getContrastingTextColor(bgColor) {
  function hexToRgb(hex) {
    hex = hex.replace(/^#/, '');
    let r = parseInt(hex.substring(0, 2), 16);
    let g = parseInt(hex.substring(2, 4), 16);
    let b = parseInt(hex.substring(4, 6), 16);
    return { r, g, b };
  }

  let { r, g, b } = hexToRgb(bgColor);
  let brightness = (r * 299 + g * 587 + b * 114) / 1000;

  return brightness < 128 ? "#FFFF00" : "#000000";
}