Home→
Time-of-Day Behavioral Tagger
⏰

Time-of-Day Behavioral Tagger

Temporal User Segmentation

Automatically segments visitors based on time-of-day patterns, business hours, and behavioral timing to enable time-sensitive personalization and targeted messaging campaigns.

BehavioralIntermediateBehavioral Tracking

Key Features

✓Automatic timezone detection
✓Business hours classification
✓Time-based user segmentation
✓Behavioral pattern analysis
✓Custom time zone support
✓Weekend/weekday detection

Script Overview

📖

What It Does

This script analyzes the visitor's local time to create behavioral segments based on when they visit your site. It detects timezone, classifies visits into business hours, weekend/weekday patterns, and pushes detailed temporal data to GTM for personalized messaging and analytics.

🎯

Use Case

Great for businesses with time-sensitive offers or different messaging for business hours. Perfect for B2B companies that want to tailor messaging based on when prospects are most likely to be working vs browsing personally.

✨

Key Benefits

  • •Time-based visitor segmentation for personalization
  • •Business hours vs after-hours visitor classification
  • •Weekend and weekday behavioral analysis
  • •Timezone-aware visitor insights
  • •Enhanced behavioral targeting capabilities
  • •Temporal conversion pattern analysis

JavaScript Code

<script>
(function() {
  'use strict';
  
  // Time-of-Day Behavioral Tagger Script
  // Version: 1.0
  // Description: Segments visitors by time patterns and behavior
  // Last Updated: 2026-02-04
  
  // Configuration
  var config = {
    // Business hours configuration (24-hour format)
    businessHours: {
      start: 9,  // 9 AM
      end: 17,   // 5 PM
      timezone: 'auto' // 'auto' to detect, or specify like 'America/New_York'
    },
    
    // Weekend configuration
    weekendDays: [0, 6], // Sunday = 0, Saturday = 6
    
    // Time segments configuration
    timeSegments: {
      'early-morning': { start: 5, end: 9 },    // 5 AM - 9 AM
      'morning': { start: 9, end: 12 },         // 9 AM - 12 PM
      'afternoon': { start: 12, end: 17 },      // 12 PM - 5 PM
      'evening': { start: 17, end: 21 },        // 5 PM - 9 PM
      'night': { start: 21, end: 24 },          // 9 PM - 12 AM
      'late-night': { start: 0, end: 5 }        // 12 AM - 5 AM
    },
    
    // DataLayer event configuration
    events: {
      timeSegment: 'time_behavioral_tag',
      sessionAnalysis: 'session_time_analysis'
    },
    
    // Storage for session analysis
    storageKey: 'time_behavioral_data',
    
    // Debug mode
    debug: false
  };

  // Utility functions
  function debugLog(message, data) {
    if (config.debug) {
      console.log('[Time Tagger] ' + message, data || '');
    }
  }

  function getCurrentTimeInfo() {
    var now = new Date();
    var timeInfo = {
      timestamp: now.getTime(),
      iso: now.toISOString(),
      
      // Local time information
      localHour: now.getHours(),
      localMinute: now.getMinutes(),
      localDay: now.getDay(), // 0 = Sunday, 6 = Saturday
      localDate: now.getDate(),
      localMonth: now.getMonth() + 1,
      localYear: now.getFullYear(),
      
      // Timezone information
      timezoneOffset: now.getTimezoneOffset(),
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'
    };
    
    return timeInfo;
  }

  function getTimeSegment(hour) {
    for (var segment in config.timeSegments) {
      var segmentConfig = config.timeSegments[segment];
      
      // Handle segments that cross midnight
      if (segmentConfig.start > segmentConfig.end) {
        if (hour >= segmentConfig.start || hour < segmentConfig.end) {
          return segment;
        }
      } else {
        if (hour >= segmentConfig.start && hour < segmentConfig.end) {
          return segment;
        }
      }
    }
    
    return 'unknown';
  }

  function isBusinessHours(hour, day) {
    // Check if it's a weekend
    if (config.weekendDays.includes(day)) {
      return false;
    }
    
    // Check if within business hours
    return hour >= config.businessHours.start && hour < config.businessHours.end;
  }

  function isWeekend(day) {
    return config.weekendDays.includes(day);
  }

  function getBehavioralClassification(timeInfo) {
    var classification = {
      timeSegment: getTimeSegment(timeInfo.localHour),
      isBusinessHours: isBusinessHours(timeInfo.localHour, timeInfo.localDay),
      isWeekend: isWeekend(timeInfo.localDay),
      dayType: isWeekend(timeInfo.localDay) ? 'weekend' : 'weekday',
      hourCategory: timeInfo.localHour < 12 ? 'am' : 'pm'
    };
    
    // Advanced behavioral insights
    if (classification.isBusinessHours && !classification.isWeekend) {
      classification.behaviorType = 'business-browsing';
      classification.intent = 'professional';
    } else if (classification.isWeekend) {
      classification.behaviorType = 'leisure-browsing';
      classification.intent = 'personal';
    } else if (!classification.isBusinessHours && !classification.isWeekend) {
      classification.behaviorType = 'after-hours-browsing';
      classification.intent = 'mixed';
    } else {
      classification.behaviorType = 'general-browsing';
      classification.intent = 'unknown';
    }
    
    return classification;
  }

  function getSessionTimePattern() {
    try {
      var stored = sessionStorage.getItem(config.storageKey + '_session');
      if (stored) {
        return JSON.parse(stored);
      }
    } catch (e) {
      debugLog('Error reading session time data:', e);
    }
    return null;
  }

  function updateSessionTimePattern(timeInfo, classification) {
    try {
      var sessionData = getSessionTimePattern() || {
        sessionStart: timeInfo.timestamp,
        visitCount: 0,
        timeSegments: [],
        behaviorTypes: []
      };
      
      sessionData.visitCount += 1;
      sessionData.lastVisit = timeInfo.timestamp;
      sessionData.sessionDuration = timeInfo.timestamp - sessionData.sessionStart;
      
      // Track unique time segments in this session
      if (!sessionData.timeSegments.includes(classification.timeSegment)) {
        sessionData.timeSegments.push(classification.timeSegment);
      }
      
      // Track unique behavior types in this session
      if (!sessionData.behaviorTypes.includes(classification.behaviorType)) {
        sessionData.behaviorTypes.push(classification.behaviorType);
      }
      
      sessionStorage.setItem(config.storageKey + '_session', JSON.stringify(sessionData));
      return sessionData;
    } catch (e) {
      debugLog('Error updating session time data:', e);
      return null;
    }
  }

  function getHistoricalTimePattern() {
    try {
      var stored = localStorage.getItem(config.storageKey);
      if (stored) {
        var data = JSON.parse(stored);
        
        // Clean old data (keep only last 30 days)
        var thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
        if (data.visits) {
          data.visits = data.visits.filter(function(visit) {
            return visit.timestamp > thirtyDaysAgo;
          });
        }
        
        return data;
      }
    } catch (e) {
      debugLog('Error reading historical time data:', e);
    }
    
    return {
      visits: [],
      patterns: {},
      preferences: {}
    };
  }

  function updateHistoricalTimePattern(timeInfo, classification) {
    try {
      var historical = getHistoricalTimePattern();
      
      // Add current visit
      historical.visits.push({
        timestamp: timeInfo.timestamp,
        timeSegment: classification.timeSegment,
        behaviorType: classification.behaviorType,
        isBusinessHours: classification.isBusinessHours,
        isWeekend: classification.isWeekend
      });
      
      // Update patterns
      historical.patterns.mostCommonTimeSegment = getMostCommonValue(
        historical.visits.map(function(v) { return v.timeSegment; })
      );
      
      historical.patterns.mostCommonBehaviorType = getMostCommonValue(
        historical.visits.map(function(v) { return v.behaviorType; })
      );
      
      // Calculate preferences
      var businessHoursVisits = historical.visits.filter(function(v) { return v.isBusinessHours; });
      var weekendVisits = historical.visits.filter(function(v) { return v.isWeekend; });
      
      historical.preferences.businessHoursFrequency = businessHoursVisits.length / historical.visits.length;
      historical.preferences.weekendFrequency = weekendVisits.length / historical.visits.length;
      historical.preferences.totalVisits = historical.visits.length;
      
      localStorage.setItem(config.storageKey, JSON.stringify(historical));
      return historical;
    } catch (e) {
      debugLog('Error updating historical time data:', e);
      return null;
    }
  }

  function getMostCommonValue(array) {
    var counts = {};
    var mostCommon = array[0];
    var maxCount = 1;
    
    array.forEach(function(item) {
      counts[item] = (counts[item] || 0) + 1;
      if (counts[item] > maxCount) {
        mostCommon = item;
        maxCount = counts[item];
      }
    });
    
    return mostCommon;
  }

  function pushToDataLayer(timeInfo, classification, sessionData, historicalData) {
    window.dataLayer = window.dataLayer || [];
    
    // Main time behavioral event
    var eventData = {
      event: config.events.timeSegment,
      
      // Current time information
      time_segment: classification.timeSegment,
      is_business_hours: classification.isBusinessHours,
      is_weekend: classification.isWeekend,
      day_type: classification.dayType,
      behavior_type: classification.behaviorType,
      intent_type: classification.intent,
      
      // Time details
      local_hour: timeInfo.localHour,
      local_day: timeInfo.localDay,
      timezone: timeInfo.timezone,
      
      // Session information
      session_visit_count: sessionData ? sessionData.visitCount : 1,
      session_time_segments: sessionData ? sessionData.timeSegments : [classification.timeSegment],
      
      // Historical patterns (if available)
      visitor_time_preference: historicalData ? historicalData.patterns.mostCommonTimeSegment : classification.timeSegment,
      visitor_behavior_preference: historicalData ? historicalData.patterns.mostCommonBehaviorType : classification.behaviorType,
      business_hours_frequency: historicalData ? Math.round(historicalData.preferences.businessHoursFrequency * 100) : null,
      weekend_frequency: historicalData ? Math.round(historicalData.preferences.weekendFrequency * 100) : null
    };
    
    window.dataLayer.push(eventData);
    
    // Session analysis event (if multiple visits in session)
    if (sessionData && sessionData.visitCount > 1) {
      window.dataLayer.push({
        event: config.events.sessionAnalysis,
        session_duration_minutes: Math.round(sessionData.sessionDuration / (1000 * 60)),
        session_time_segments_count: sessionData.timeSegments.length,
        session_behavior_diversity: sessionData.behaviorTypes.length
      });
    }
    
    debugLog('Time behavioral data pushed to dataLayer:', eventData);
  }

  // Main execution
  function initTimeBehavioralTagger() {
    debugLog('Initializing Time Behavioral Tagger');
    
    var timeInfo = getCurrentTimeInfo();
    var classification = getBehavioralClassification(timeInfo);
    
    debugLog('Time classification:', classification);
    
    // Update session and historical data
    var sessionData = updateSessionTimePattern(timeInfo, classification);
    var historicalData = updateHistoricalTimePattern(timeInfo, classification);
    
    // Push to dataLayer
    pushToDataLayer(timeInfo, classification, sessionData, historicalData);
  }

  // Initialize when DOM is ready
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initTimeBehavioralTagger);
  } else {
    initTimeBehavioralTagger();
  }

  // Expose utility functions
  window.timeBehavioralTagger = {
    getCurrentClassification: function() {
      var timeInfo = getCurrentTimeInfo();
      return getBehavioralClassification(timeInfo);
    },
    getSessionData: function() {
      return getSessionTimePattern();
    },
    getHistoricalData: function() {
      return getHistoricalTimePattern();
    },
    clearHistoricalData: function() {
      localStorage.removeItem(config.storageKey);
      debugLog('Historical time data cleared');
    },
    refreshAnalysis: function() {
      initTimeBehavioralTagger();
    }
  };

})();
</script>

💡 Pro Tip: Copy the entire code block above and paste it directly into a GTM Custom HTML tag. The script is self-contained and ready to use immediately.